Screening Questions
! Time Duration
Variable: continuous
Method: check normality + kruskal-wallis
test + post-hoc test
Result: p< 0.05–> we can reject the hypothesis
controlled group is significantly different from (error bar; shaded
bar; fanchart slice; BUT NOT fanchartslice)
time_duration_table <- rawdata_value[,c("Duration (in seconds)", "group")]
time_duration_table$`Duration (in mins)` <- as.numeric(time_duration_table$`Duration (in seconds)`)/60
# report quantile information
summary(time_duration_table$`Duration (in mins)`)
Min. 1st Qu. Median Mean 3rd Qu. Max.
4.117 13.967 19.883 22.524 27.133 85.233
# test for normality --> It's definitely not normal distribution
# shapiro.test(time_duration_table$`Duration (in mins)`)
# run the kruskal-wallis test
kruskal_test <- kruskal.test(`Duration (in mins)` ~ group, data = time_duration_table)
print(kruskal_test)
Kruskal-Wallis rank sum test
data: Duration (in mins) by group
Kruskal-Wallis chi-squared = 22.226, df = 4, p-value = 0.0001807
# run post-hoc test
dunn_test <- dunnTest(`Duration (in mins)` ~ group, data = time_duration_table, method = "bonferroni")
Warning: group was coerced to a factor.
print(dunn_test)
Dunn (1964) Kruskal-Wallis multiple comparison
p-values adjusted with the Bonferroni method.
Time duration summary table
time_duration_summary <- time_duration_table %>%
group_by(group) %>%
summarise(mean_duration = mean(`Duration (in mins)`, na.rm = TRUE),
sd_duration = sd(`Duration (in mins)`, na.rm = TRUE),
.groups = 'drop')
Plot the distribution of different groups

Plot time duration bar chart. It’s not valid as the data is not
normal distribution.
ggplot(time_duration_summary, aes(x = group, y = mean_duration)) +
geom_bar(stat = "identity", fill = "steelblue", width = 0.6) +
geom_errorbar(aes(ymin = mean_duration - sd_duration, ymax = mean_duration + sd_duration), width = 0.2) +
labs(title = "Response Duration by Group",
y = "Duration (in minutes)",
x = "Group") +
theme_minimal()

Q3.2 Age
What is your age?
Variable: continuous
Method:
kruskal-wallis test
Result: Fail to reject the null
hypothesis
kruskal_test <- kruskal.test(`Q3.2` ~ group, data = age_table)
print(kruskal_test)
Kruskal-Wallis rank sum test
data: Q3.2 by group
Kruskal-Wallis chi-squared = 2.5182, df = 4, p-value = 0.6414
Q3.3 Gender
Which of the following best describes your gender identity?
Variable: categorical
Method: contingency Table + chi-squared test
Result: Fail to reject the null hypothesis
q3_3_table <- rawdata_value[, c("Q3.3", "group")]
# q3_3_table$Q3.3 <- recode(q3_3_table$Q3.3,
# "1" = "Male",
# "2" = "Female",
# .default = "Other")
q3_3_contingency <- table(q3_3_table$Q3.3, q3_3_table$group)
print(q3_3_contingency)
bellcurve controlled errorbar fanchartslice shadedbar
1 30 32 28 34 27
2 32 33 31 29 35
3 0 0 1 0 1
4 0 0 1 0 0
# Chi-squared test
chisq.test(q3_3_contingency)
Warning: Chi-squared approximation may be incorrect
Pearson's Chi-squared test
data: q3_3_contingency
X-squared = 8.6715, df = 12, p-value = 0.7307
Calculate the gender percentage
# percentage of male
male_per <- q3_3_contingency[1,]
gender_group_total <- colSums(q3_3_contingency)
male_prop <- male_per/gender_group_total
Q3.4 Highest Education
What is your highest level of education achieved?
Variable: categorical with written insights from choice 9 Method:
contingency Table + chi-squared test
Result: Fail to reject the null hypothesis
q3_4_table <- rawdata_value[rawdata_value$`Q3.4` != "9", c("Q3.4", "group")]
q3_4_contingency <- table(q3_4_table$Q3.4, q3_4_table$group)
# Chi-squared test
chisq.test(q3_4_contingency)
Warning: Chi-squared approximation may be incorrect
Pearson's Chi-squared test
data: q3_4_contingency
X-squared = 19.937, df = 28, p-value = 0.8667
Highest Education Level proportion bar plot across different
groups
q3_4_prop <- as.data.frame(q3_4_contingency)
# rename columns
names(q3_4_prop) <- c("Q3.4", "Group", "Count")
# calculate proportions within each group
q3_4_prop <- q3_4_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(q3_4_prop, aes(x = as.factor(`Q3.4`), y = Proportion, fill = Group)) +
geom_bar(stat = "identity", position = "dodge") +
facet_wrap(~ Group) +
labs(
title = "Q3.4 Highest Education Level Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
# scale_x_discrete(labels = c(
# "1" = "No formal education",
# "2" = "Primary/Elementary",
# "3" = "Secondary School (GCSE)",
# "4" = "High School (A Level)",
# "5" = "Technical or Vocational",
# "6" = "Bachelors or equivalent degree level qualification",
# "7" = "Masters or equivalent higher degree level qualification",
# "8" = "PhD or equivalent doctoral level qualification"))+
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot pie chart including all participants
q3_4_table <- rawdata_value[, c("Q3.4", "group")]
# Q3.4 summary table
q3_4_summary <- q3_4_table %>%
group_by(`Q3.4`) %>%
summarise(count = n()) %>%
mutate(proportion = count / sum(count),
label =
case_when(
Q3.4 == "1" ~ "1-No formal education",
Q3.4 == "2" ~ "2-Primary/Elementary",
Q3.4 == "3" ~ "3-Secondary School (GCSE)",
Q3.4 == "4" ~ "4-High School (A Level)",
Q3.4 == "5" ~ "5-Technical or Vocational",
Q3.4 == "6" ~ "6-Bachelors or equivalent degree level qualification",
Q3.4 == "7" ~ "7-Masters or equivalent higher degree level qualification",
Q3.4 == "8" ~ "8-PhD or equivalent doctoral level qualification",
Q3.4 == "9" ~ "9-Other"
),
label = paste0(label, " (", round(proportion * 100, 2), " %)")
)
ggplot(q3_4_summary, aes(x = "",y = proportion, fill = label)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
labs(title = "Q3.4 Highest Education Level Summary Pie Chart",
x = "",
y = "") +
theme_minimal() +
theme(axis.text.x = element_blank())

Q3.5 Employee Status
What is your current profession or employment status?
Variable: categorical
Method: contingency Table + chi-squared test
Result: Fail to reject the null hypothesis
q3_5_table <- rawdata_value[rawdata_value$`Q3.5` != "6", c("Q3.5", "group")]
q3_5_contingency <- table(q3_5_table$Q3.5, q3_5_table$group)
# print(q3_5_contingency)
# Chi-squared test
chisq.test(q3_5_contingency)
Warning: Chi-squared approximation may be incorrect
Pearson's Chi-squared test
data: q3_5_contingency
X-squared = 17.324, df = 16, p-value = 0.3649
Employee status proportion bar plot across different groups
q3_5_prop <- as.data.frame(q3_5_contingency)
# rename columns
names(q3_5_prop) <- c("Q3.5", "Group", "Count")
# calculate proportions within each group
q3_5_prop <- q3_5_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(q3_5_prop, aes(x = as.factor(`Q3.5`), y = Proportion, fill = Group)) +
geom_bar(stat = "identity", position = "dodge") +
# facet_wrap(~ Group) +
labs(
title = "Q3.5 Employee Status Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_x_discrete(labels = c(
"1" = "Student",
"2" = "Employed",
"3" = "Self-employed",
"4" = "Retired",
"5" = "Unemployed"
)) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot pie chart including all participants
q3_5_table <- rawdata_value[, c("Q3.5", "group")]
q3_5_summary <- q3_5_table %>%
group_by(`Q3.5`) %>%
summarise(count = n()) %>%
mutate(proportion = count / sum(count),
label =
case_when(
Q3.5 == "1" ~ "1-Student",
Q3.5 == "2" ~ "2-Employed",
Q3.5 == "3" ~ "3-Self-employed",
Q3.5 == "4" ~ "4-Retired",
Q3.5 == "5" ~ "5-Unemployed",
Q3.5 == "6" ~ "6-Other"
),
label = paste0(label, " (", round(proportion * 100, 2), " %)")
)
ggplot(q3_5_summary, aes(x = "",y = proportion, fill = label)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
labs(title = "Q3.5 Employee Status Summary Pie Chart",
x = "",
y = "") +
theme_minimal() +
theme(axis.text.x = element_blank())

Q3.6 Economics Education
In which, if any, have you ever studied economics? (Select all that
apply)
Variable: categorical
Method: convert to list and count + chi-squared test
Result: Fail to reject the null hypothesis
Plot percentage bar chart including all participants
q3_6_table <- rawdata_value[, c("Q3.6", "group")]
q3_6_table$Q3.6 <- lapply(q3_6_table$Q3.6, function(x) as.list(as.numeric(strsplit(x, ",")[[1]])))
# count the number of occurrences of each value
q3_6_summary <- q3_6_table %>%
unnest(Q3.6) %>%
group_by(`Q3.6`) %>%
summarise(count = n()) %>%
mutate(proportion = count / total_respondents,
label =
case_when(
Q3.6 == "1" ~ "1-At school",
Q3.6 == "2" ~ "2-In higher education",
Q3.6 == "3" ~ "3-Through self-directed study",
Q3.6 == "4" ~ "4-Self-motivated study",
Q3.6 == "5" ~ "5-Never studied economics",
Q3.6 == "6" ~ "6-Don’t know / can’t recall",
Q3.6 == "7" ~ "7-Other"
))
# q3_6_summary$Q3.6 <- as.numeric(q3_6_summary$Q3.6)
ggplot(q3_6_summary, aes(x = factor(label), y = proportion)) +
geom_col(fill = "steelblue") +
geom_text(aes(label = paste0(round(proportion * 100, 1), "%")),
vjust = -0.3, size = 3.5) +
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
labs(
title = "Percentage of Participants Selecting Each Q3.6 Option",
x = "Response",
y = "Percentage of Participants"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

q3_6_table <- rawdata_value[, c("Q3.6", "group")]
q3_6_table$Q3.6 <- lapply(q3_6_table$Q3.6, function(x) as.list(as.numeric(strsplit(x, ",")[[1]])))
# count the number of occurrences of each value
q3_6_prop <- q3_6_table %>%
unnest(Q3.6) %>%
group_by(group, Q3.6) %>%
summarise(count = n(), .groups = 'drop')
q3_6_prop$Q3.6 <- as.numeric(q3_6_prop$Q3.6)
# create a contingency table
q3_6_contingency <- xtabs(count ~ Q3.6 + group, data = q3_6_prop)
print(q3_6_contingency)
group
Q3.6 0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 12 20 13 16 21
2 8 10 17 18 11
3 4 8 8 7 5
4 4 6 5 8 5
5 36 28 28 28 26
6 2 0 1 1 1
7 0 2 0 0 1
# Chi-squared test
chisq.test(q3_6_contingency)
Warning: Chi-squared approximation may be incorrect
Pearson's Chi-squared test
data: q3_6_contingency
X-squared = 22.428, df = 24, p-value = 0.5537
# q3_6_test <-q3_6_prop %>%
# group_by(`Q3.6`) %>%
# summarise(total_count = sum(count), .groups = "drop")
Economics Education proportion bar plot across different groups
# convert contingency table to data frame # count 0 as well
q3_6_prop <- as.data.frame(q3_6_contingency)
# calculate proportions within each group
q3_6_prop <- q3_6_prop %>%
left_join(group_total, by = "group") %>%
mutate(Proportion = Freq / n_respondents)
ggplot(q3_6_prop, aes(x = factor(Q3.6), y = Proportion, fill = factor(group))) +
geom_col(position = "dodge") +
labs(
title = "Q3.6 Economics Education Propotion Plot across Groups",
x = "Response",
y = "Proportion",
fill = "Group"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()

Q3.7 Financial Activities
Which of the following financial activities do you actively
participate in? (Select all that apply) - Selected Choice Fixed Income
(e.g., government bonds, corporate bonds)
Variable: categorical
Method: convert to list and count + chi-squared test
Result: Fail to reject the null hypothesis
q3_7_table <- rawdata_value[, c("Q3.7", "group")]
q3_7_table$Q3.7 <- lapply(q3_7_table$Q3.7, function(x) as.list(as.numeric(strsplit(x, ",")[[1]])))
# count the number of occurrences of each value in each group
q3_7_prop <- q3_7_table %>%
unnest(Q3.7) %>%
group_by(group,`Q3.7`) %>%
summarise(count = n(), .groups = 'drop')
q3_7_prop$Q3.7 <- as.numeric(q3_7_prop$Q3.7)
# create a contingency table
q3_7_contingency <- xtabs(count ~ `Q3.7` + group, data = q3_7_prop)
print(q3_7_contingency)
group
Q3.7 0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
11 49 53 51 59 48
12 25 32 29 33 26
13 9 16 8 7 10
14 29 35 31 25 29
15 3 13 5 9 4
16 1 8 2 6 6
17 9 14 13 12 9
18 4 4 5 2 7
19 1 2 0 0 0
# Chi-squared test
chisq.test(q3_7_contingency)
Warning: Chi-squared approximation may be incorrect
Pearson's Chi-squared test
data: q3_7_contingency
X-squared = 28.26, df = 32, p-value = 0.6564
Plot financial activities proportion bar plot across different
groups
# convert contingency table to data frame
q3_7_prop <- as.data.frame(q3_7_contingency) %>%
left_join(group_total, by = "group") %>%
mutate(Proportion = Freq / n_respondents)
ggplot(q3_7_prop, aes(x = factor(`Q3.7`), y = Proportion, fill = factor(group))) +
geom_col(position = "dodge") +
labs(
title = "Q3.7 Financial Activities Propotion Plot across Groups",
x = "Response",
y = "Proportion",
fill = "Group"
) +
scale_x_discrete(labels = c(
"11" = "Savings",
"12" = "Investments",
"13" = "Fixed Income",
"14" = "Retirement Planning",
"15" = "Trading",
"16" = "Real Estate",
"17" = "Cryptocurrencies",
"18" = "None of the above",
"19" = "Other"
)) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot percentage bar chart including all participants
q3_7_summary <-q3_7_prop %>%
group_by(`Q3.7`) %>%
summarise(total_count = sum(Freq), .groups = "drop") %>%
mutate(proportion = total_count / total_respondents,
label =
case_when(
`Q3.7` == "11" ~ "11-Savings",
`Q3.7` == "12" ~ "12-Investments",
`Q3.7` == "13" ~ "13-Fixed Income",
`Q3.7` == "14" ~ "14-Retirement Planning",
`Q3.7` == "15" ~ "15-Trading",
`Q3.7` == "16" ~ "16-Real Estate",
`Q3.7` == "17" ~ "17-Cryptocurrencies",
`Q3.7` == "18" ~ "18-None of the above",
`Q3.7` == "19" ~ "19-Other"
))
ggplot(q3_7_summary, aes(x = factor(label), y = proportion)) +
geom_col(fill = "steelblue") +
geom_text(aes(label = paste0(round(proportion * 100, 1), "%")),
vjust = -0.3, size = 3.5) +
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
labs(
title = "Percentage of Participants Selecting Each Q3.7 Option",
x = "Response",
y = "Percentage of Participants"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Q3.8 Awareness of Economics
How frequently, if at all, do you read/watch/listen to news stories
related to economics or the economy?
Variable: categorical
Method: contingency table + chi-squared test
Result: Fail to reject the null hypothesis
chisq.test(q3_8_contingency[-nrow(q3_8_contingency), ])
Warning: Chi-squared approximation may be incorrect
Pearson's Chi-squared test
data: q3_8_contingency[-nrow(q3_8_contingency), ]
X-squared = 30.527, df = 20, p-value = 0.06175
Awareness of Economics proportion bar plot across different
groups
q3_8_prop <- as.data.frame(q3_8_contingency)
# rename columns
names(q3_8_prop) <- c("Q3.8", "Group", "Count")
# add a labelled column
q3_8_prop <- q3_8_prop %>%
mutate(Q3.8_label = case_when(
Q3.8 == "1" ~ "1-Never",
Q3.8 == "2" ~ "2-Rarely",
Q3.8 == "3" ~ "3-Monthly",
Q3.8 == "4" ~ "4-Weekly",
Q3.8 == "5" ~ "5-Almost daily",
Q3.8 == "6" ~ "6-Every day",
Q3.8 == "7" ~ "7-Not sure"
))
# calculate proportions within each group
q3_8_prop <- q3_8_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(q3_8_prop, aes(x = as.factor(`Q3.8_label`), y = Proportion, fill = Group)) +
geom_col(position = "dodge") +
# facet_wrap(~ Group) +
labs(
title = "Q3.8 Awareness of Economics Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot pie chart including all participants
q3_8_summary <- q3_8_prop %>%
group_by(`Q3.8_label`) %>%
summarise(total_count = sum(Count), .groups = "drop") %>%
mutate(proportion = total_count / sum(total_count),
`Q3.8_label` = paste0(`Q3.8_label`, " (", round(proportion * 100, 2), " %)"))
ggplot(q3_8_summary, aes(x = "",y = proportion, fill = `Q3.8_label`)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
labs(title = "Q3.8 Awareness of Economics Summary Pie Chart",
x = "",
y = "") +
theme_minimal() +
theme(axis.text.x = element_blank())
Q3.9 Inflation Knowledge
To the best of your knowledge, which option most accurately describes
what inflation is?
Definitive correct answer
Variable: categorical
Method: descriptive analysis
Respondents were filtered based on whether if they can
understand what inflation is.
q3_9_table <- rawdata_q3_9[, c("Q3.9", "group")]
q3_9_summary <- q3_9_table %>%
group_by(`Q3.9`) %>%
summarise(count = n()) %>%
mutate(proportion = count / sum(count))
ggplot(q3_9_summary, aes(x = "",y = proportion, fill = `Q3.9`)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
labs(title = "Q3.9 Inflation Knowledge Summary Pie Chart",
x = "",
y = "") +
theme_minimal() +
theme(axis.text.x = element_blank())

Q3.11 Trust of Official Data
How much do you trust official inflation forecasts (For instance, the
forecasts released by the Bank of England)?
ascending value-increasing trust + exclude 6- Unsure / no
opinion
Variable: treat as continuous
Method: Kruskal-Wallis test
Result: Fail to reject the null hypothesis
q3_11_table <- rawdata_value[rawdata_value$`Q3.11` != "6", c("Q3.11", "group")]
q3_11_table$Q3.11 <- as.numeric(q3_11_table$`Q3.11`)
# check normality --> Not normally distributed
# shapiro.test(q3_11_table$Q3.11)
# bartlett.test(`Q3.11` ~ group, data = q3_11_table)
# run kruskal test
kruskal_test <- kruskal.test(Q3.11 ~ group, data = q3_11_table)
print(kruskal_test)
Kruskal-Wallis rank sum test
data: Q3.11 by group
Kruskal-Wallis chi-squared = 3.4585, df = 4, p-value = 0.4842
q3_11_summary <- q3_11_table %>%
group_by(group) %>%
summarise(q3_11_mean = mean(as.numeric(Q3.11), na.rm = TRUE),
q3_11_sd = sd(as.numeric(Q3.11), na.rm = TRUE),
.groups = 'drop')
# report quantile information
summary(q3_11_table$Q3.11)
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 3.000 4.000 3.711 4.000 5.000
Plot the distribution of different groups
# histogram including all participants
ggplot(q3_11_table, aes(x = Q3.11)) +
geom_histogram(binwidth = 1, fill = "steelblue", color = "white") +
# facet_wrap(~ group) +
labs(title = "Q3.11 Trust official inflation forecasts distribution",
x = "Q3.11",
y = "Count") +
scale_x_continuous(breaks = seq(0, max(q3_11_table$Q3.11, na.rm = TRUE), by = 1)) +
theme_minimal()

# Grouped bar-style histogram
ggplot(q3_11_table, aes(x = factor(Q3.11), fill = factor(group))) +
geom_bar(position = "dodge") +
labs(
title = "Q3.11 Trust official inflation forecasts distribution by group",
x = "Q3.11 Response",
y = "Count",
fill = "Group"
) +
theme_minimal()

Q3.12 Frequency of Checking Current Inflation
How often do you check the current value of inflation? Variable:
categorical
Method: contingency table + chi-squared test
Result: Fail to reject the null hypothesis
# Initial Check
summary(as.numeric(rawdata_value$Q3.12))
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 2.000 2.000 2.392 3.000 4.000
q3_12_table <- rawdata_value[, c("Q3.12", "group")]
q3_12_contingency <- table(q3_12_table$Q3.12, q3_12_table$group)
print(q3_12_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 6 5 10 7 6
2 30 24 27 20 27
3 16 25 21 29 22
4 4 5 2 5 2
# Chi-squared test
chisq.test(q3_12_contingency)
Warning: Chi-squared approximation may be incorrect
Pearson's Chi-squared test
data: q3_12_contingency
X-squared = 10.744, df = 12, p-value = 0.5509
Frequency of Checking Current Inflation proportion bar plot across
different groups
q3_12_prop <- as.data.frame(q3_12_contingency)
# rename columns
names(q3_12_prop) <- c("Q3.12", "Group", "Count")
# add a labelled column
q3_12_prop <- q3_12_prop %>%
mutate(Q3.12_label = case_when(
Q3.12 == "1" ~ "1-Never",
Q3.12 == "2" ~ "2-Rarely",
Q3.12 == "3" ~ "3-Sometimes",
Q3.12 == "4" ~ "4-Often"
))
# calculate proportions within each group
q3_12_prop <- q3_12_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(q3_12_prop, aes(x = as.factor(`Q3.12_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
labs(
title = "Q3.12 Frequency of Checking Current Inflation Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

NA
Plot pie chart including all participants
q3_12_summary <- q3_12_prop %>%
group_by(`Q3.12_label`) %>%
summarise(total_count = sum(Count), .groups = "drop") %>%
mutate(proportion = total_count / sum(total_count),
`Q3.12_label` = paste0(`Q3.12_label`, " (", round(proportion * 100, 2), " %)"))
ggplot(q3_12_summary, aes(x = "",y = proportion, fill = `Q3.12_label`)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
labs(title = "Q3.12 Frequency of Checking Current Inflation Summary Pie Chart",
x = "",
y = "") +
theme_minimal() +
theme(axis.text.x = element_blank())

Q3.13 Source of Current Inflation
Which source do you rely on to inform yourself about the current
value of inflation?
Variable: categorical
Method: convert to list and count + chi-squared test
Result: Fail to reject the null hypothesis
q3_13_table <- rawdata_value[, c("Q3.13", "group")]
q3_13_table$Q3.13 <- lapply(q3_13_table$Q3.13, function(x) as.list(as.numeric(strsplit(x, ",")[[1]])))
# count the number of occurrences of each value
q3_13_prop <- q3_13_table %>%
unnest(Q3.13) %>%
group_by(group,`Q3.13`) %>%
summarise(count = n(), .groups = 'drop')
q3_13_prop$Q3.13 <- as.numeric(q3_13_prop$Q3.13)
# create a contingency table
q3_13_contingency <- xtabs(count ~ `Q3.13` + group, data = q3_13_prop)
print(q3_13_contingency)
group
Q3.13 0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 43 41 33 44 36
2 16 16 15 13 16
3 24 28 26 29 21
4 5 7 8 4 10
5 15 15 22 21 17
6 6 6 7 4 11
7 15 13 15 19 13
8 5 8 5 5 1
9 2 0 0 0 0
# Chi-squared test
chisq.test(q3_13_contingency)
Warning: Chi-squared approximation may be incorrect
Pearson's Chi-squared test
data: q3_13_contingency
X-squared = 28.283, df = 32, p-value = 0.6553
Plot source of current inflation proportion bar plot across different
groups
# convert contingency table to data frame
q3_13_prop <- as.data.frame(q3_13_contingency) %>%
left_join(group_total, by = "group") %>%
mutate(Proportion = Freq / n_respondents)
# add a labelled column
q3_13_prop <- q3_13_prop %>%
mutate(Q3.13_label = case_when(
`Q3.13` == "1" ~ "1-Television, radio or print media",
`Q3.13` == "2" ~ "2-Social media",
`Q3.13` == "3" ~ "3-Official websites or data releases",
`Q3.13` == "4" ~ "4-Content platform",
`Q3.13` == "5" ~ "5-Actively search on search engines",
`Q3.13` == "6" ~ "6-Family or friends",
`Q3.13` == "7" ~ "7-Financial advice websites/forums",
`Q3.13` == "8" ~ "8-Private banks or economic research institutes",
`Q3.13` == "9" ~ "9-Other"
))
ggplot(q3_13_prop, aes(x = factor(`Q3.13_label`), y = Proportion, fill = group)) +
geom_col(position = "dodge") +
labs(
title = "Q3.13 Source of Current Inflation Propotion Plot across Groups",
x = "Response",
y = "Proportion",
fill = "Group"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot percentage bar chart including all participants
q3_13_summary <- q3_13_prop %>%
group_by(`Q3.13_label`) %>%
summarise(total_count = sum(Freq), .groups = "drop") %>%
mutate(proportion = total_count / total_respondents)
ggplot(q3_13_summary, aes(x = factor(Q3.13_label), y = proportion)) +
geom_col(fill = "steelblue") +
geom_text(aes(label = paste0(round(proportion * 100, 1), "%")),
vjust = -0.3, size = 3.5) +
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
labs(
title = "Percentage of Participants Selecting Each Q3.13 Option",
x = "Response",
y = "Percentage of Participants"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Q3.14 Impact of Current Inflation
To what extent do you feel that the current value of inflation is
impacting your personal finances? Variable: categorical
Method: contingency table + chi-squared test
Result: Fail to reject the null hypothesis
# Initial Check
summary(as.numeric(rawdata_value$Q3.14))
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 2.000 3.000 2.826 3.000 4.000
q3_14_table <- rawdata_value[, c("Q3.14", "group")]
q3_14_contingency <- table(q3_14_table$Q3.14, q3_14_table$group)
print(q3_14_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 3 0 4 0 1
2 22 18 19 19 18
3 22 30 25 28 23
4 9 11 12 14 15
# Chi-squared test
chisq.test(q3_14_contingency)
Warning: Chi-squared approximation may be incorrect
Pearson's Chi-squared test
data: q3_14_contingency
X-squared = 12.14, df = 12, p-value = 0.4345
Impact of Current Inflation proportion bar plot across different
groups
q3_14_prop <- as.data.frame(q3_14_contingency)
# rename columns
names(q3_14_prop) <- c("Q3.14", "Group", "Count")
# add a labelled column
q3_14_prop <- q3_14_prop %>%
mutate(Q3.14_label = case_when(
Q3.14 == "1" ~ "1-Not at all",
Q3.14 == "2" ~ "2-Slightly",
Q3.14 == "3" ~ "3-Moderately",
Q3.14 == "4" ~ "4-Very significantly"
))
# calculate proportions within each group
q3_14_prop <- q3_14_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(q3_14_prop, aes(x = as.factor(`Q3.14_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
labs(
title = "Q3.14 Impact of Current Inflation Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot pie chart including all participants
q3_14_summary <- q3_14_prop %>%
group_by(`Q3.14_label`) %>%
summarise(total_count = sum(Count), .groups = "drop") %>%
mutate(proportion = total_count / sum(total_count),
`Q3.14_label` = paste0(`Q3.14_label`, " (", round(proportion * 100, 2), " %)"))
ggplot(q3_14_summary, aes(x = "",y = proportion, fill = `Q3.14_label`)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
labs(title = "Q3.14 Impact of Current Inflation Summary Pie Chart",
x = "",
y = "") +
theme_minimal() +
theme(axis.text.x = element_blank())

Q3.15 Response to Current Inflation
How much do you adjust or take action in response to the change in
current value of inflation?
Variable: categorical
Method: contingency table + chi-squared test
Result: Fail to reject the null hypothesis
# Initial Check
summary(as.numeric(rawdata_value$Q3.15))
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 2.000 3.000 2.519 3.000 4.000
q3_15_table <- rawdata_value[, c("Q3.15", "group")]
q3_15_contingency <- table(q3_15_table$Q3.15, q3_15_table$group)
print(q3_15_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 8 2 8 9 7
2 25 20 22 14 20
3 18 29 23 34 26
4 5 8 7 4 4
# Chi-squared test
chisq.test(q3_15_contingency)
Pearson's Chi-squared test
data: q3_15_contingency
X-squared = 15.333, df = 12, p-value = 0.2237
Response to Current Inflation proportion bar plot across different
groups
q3_15_prop <- as.data.frame(q3_15_contingency)
# rename columns
names(q3_15_prop) <- c("Q3.15", "Group", "Count")
# add a labelled column
q3_15_prop <- q3_15_prop %>%
mutate(Q3.15_label = case_when(
Q3.15 == "1" ~ "1-Not at all",
Q3.15 == "2" ~ "2-Rarely",
Q3.15 == "3" ~ "3-Somewhat actively",
Q3.15 == "4" ~ "4-Very actively"
))
# calculate proportions within each group
q3_15_prop <- q3_15_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(q3_15_prop, aes(x = as.factor(`Q3.15_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
labs(
title = "Q3.15 Response to Current Inflation Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot pie chart including all participants
q3_15_summary <- q3_15_prop %>%
group_by(`Q3.15_label`) %>%
summarise(total_count = sum(Count), .groups = "drop") %>%
mutate(proportion = total_count / sum(total_count),
`Q3.15_graph_label` = paste0(`Q3.15_label`, " (", round(proportion * 100, 2), " %)"))
ggplot(q3_15_summary, aes(x = "",y = proportion, fill = `Q3.15_graph_label`)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
labs(title = "Q3.15 Response to Current Inflation Summary Pie Chart",
x = "",
y = "") +
theme_minimal() +
theme(axis.text.x = element_blank())

Q3.16 Frequency of Checking Inflation Forecasts
How often do you look at inflation forecasts (that is, information
about future inflation)?
Variable: categorical
Method: contingency table + chi-squared test
Result: Fail to reject the null hypothesis
# Initial Check
summary(as.numeric(rawdata_value$Q3.16))
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 2.000 2.000 2.167 3.000 4.000
q3_16_table <- rawdata_value[, c("Q3.16", "group")]
q3_16_contingency <- table(q3_16_table$Q3.16, q3_16_table$group)
print(q3_16_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 9 14 15 12 9
2 35 23 23 27 32
3 7 19 20 18 16
4 5 3 2 4 0
# Chi-squared test
chisq.test(q3_16_contingency)
Warning: Chi-squared approximation may be incorrect
Pearson's Chi-squared test
data: q3_16_contingency
X-squared = 19.045, df = 12, p-value = 0.08745
Frequency of Checking Inflation Forecasts proportion bar plot across
different groups
q3_16_prop <- as.data.frame(q3_16_contingency)
# rename columns
names(q3_16_prop) <- c("Q3.16", "Group", "Count")
# add a labelled column
q3_16_prop <- q3_16_prop %>%
mutate(Q3.16_label = case_when(
Q3.16 == "1" ~ "1-Never",
Q3.16 == "2" ~ "2-Rarely",
Q3.16 == "3" ~ "3-Sometimes",
Q3.16 == "4" ~ "4-Often"
))
# calculate proportions within each group
q3_16_prop <- q3_16_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(q3_16_prop, aes(x = as.factor(`Q3.16_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
labs(
title = "Q3.16 Frequency of Checking Inflation Forecasts Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot pie chart including all participants
q3_16_summary <- q3_16_prop %>%
group_by(`Q3.16_label`) %>%
summarise(total_count = sum(Count), .groups = "drop") %>%
mutate(proportion = total_count / sum(total_count),
`Q3.16_label` = paste0(`Q3.16_label`, " (", round(proportion * 100, 2), " %)"))
ggplot(q3_16_summary, aes(x = "",y = proportion, fill = `Q3.16_label`)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
labs(title = "Q3.16 Frequency of Checking Inflation Forecasts Summary Pie Chart",
x = "",
y = "") +
theme_minimal() +
theme(axis.text.x = element_blank())

Q3.17 Source of Inflation Forecasts
Which source do you rely on to obtain inflation forecasts
(information about future inflation)?
Variable: categorical
Method: convert to list and count + chi-squared test
Result: Fail to reject the null hypothesis
q3_17_table <- rawdata_value[, c("Q3.17", "group")]
q3_17_table$Q3.17 <- lapply(q3_17_table$Q3.17, function(x) as.list(as.numeric(strsplit(x, ",")[[1]])))
# count the number of occurrences of each value
q3_17_prop <- q3_17_table %>%
unnest(Q3.17) %>%
group_by(group,`Q3.17`) %>%
summarise(count = n(), .groups = 'drop')
q3_17_prop$Q3.17 <- as.numeric(q3_17_prop$Q3.17)
# create a contingency table
q3_17_contingency <- xtabs(count ~ `Q3.17` + group, data = q3_17_prop)
print(q3_17_contingency)
group
Q3.17 0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 35 31 34 31 31
2 13 16 13 11 12
3 15 21 22 24 25
4 4 9 8 4 6
5 14 17 19 16 14
6 4 4 6 3 6
7 13 15 16 17 15
8 3 9 4 5 2
9 2 0 0 0 0
# Chi-squared test
chisq.test(q3_17_contingency)
Warning: Chi-squared approximation may be incorrect
Pearson's Chi-squared test
data: q3_17_contingency
X-squared = 23.655, df = 32, p-value = 0.8566
Plot source of inflation forecasts proportion bar plot across
different groups
# convert contingency table to data frame
q3_17_prop <- as.data.frame(q3_17_contingency) %>%
left_join(group_total, by = "group") %>%
mutate(Proportion = Freq / n_respondents)
# add a labelled column
q3_17_prop <- q3_17_prop %>%
mutate(Q3.17_label = case_when(
`Q3.17` == "1" ~ "1-Television, radio or print media",
`Q3.17` == "2" ~ "2-Social media",
`Q3.17` == "3" ~ "3-Official websites or data releases",
`Q3.17` == "4" ~ "4-Content platform",
`Q3.17` == "5" ~ "5-Actively search on search engines",
`Q3.17` == "6" ~ "6-Family or friends",
`Q3.17` == "7" ~ "7-Financial advice websites/forums",
`Q3.17` == "8" ~ "8-Private banks or economic research institutes",
`Q3.17` == "9" ~ "9-Other"
))
ggplot(q3_17_prop, aes(x = factor(`Q3.17_label`), y = Proportion, fill = group)) +
geom_col(position = "dodge") +
labs(
title = "Q3.17 Source of Inflation Forecasts Propotion Plot across Groups",
x = "Response",
y = "Proportion",
fill = "Group"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot percentage bar chart including all participants
q3_17_summary <- q3_17_prop %>%
group_by(`Q3.17_label`) %>%
summarise(total_count = sum(Freq), .groups = "drop") %>%
mutate(proportion = total_count / total_respondents)
ggplot(q3_17_summary, aes(x = factor(Q3.17_label), y = proportion)) +
geom_col(fill = "steelblue") +
geom_text(aes(label = paste0(round(proportion * 100, 1), "%")),
vjust = -0.3, size = 3.5) +
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
labs(
title = "Percentage of Participants Selecting Each Q3.17 Option",
x = "Response",
y = "Percentage of Participants"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Q3.18 Impact of Inflation Forecasts
To what extent do you feel that inflation forecasts (information
about future inflation) impact your personal finances?
Variable: categorical
Method: contingency table + chi-squared test
Result: Fail to reject the null hypothesis
# Initial Check
summary(as.numeric(rawdata_value$Q3.18))
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 2.000 2.000 2.321 3.000 4.000
q3_18_table <- rawdata_value[, c("Q3.18", "group")]
q3_18_contingency <- table(q3_18_table$Q3.18, q3_18_table$group)
print(q3_18_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 13 9 15 7 9
2 22 29 17 29 24
3 17 14 22 20 18
4 4 7 6 5 6
# Chi-squared test
chisq.test(q3_18_contingency)
Pearson's Chi-squared test
data: q3_18_contingency
X-squared = 10.822, df = 12, p-value = 0.5443
Impact of Inflation Forecasts proportion bar plot across different
groups
q3_18_prop <- as.data.frame(q3_18_contingency)
# rename columns
names(q3_18_prop) <- c("Q3.18", "Group", "Count")
# add a labelled column
q3_18_prop <- q3_18_prop %>%
mutate(Q3.18_label = case_when(
Q3.18 == "1" ~ "1-Not at all",
Q3.18 == "2" ~ "2-Slightly",
Q3.18 == "3" ~ "3-Moderately",
Q3.18 == "4" ~ "4-Very significantly"
))
# calculate proportions within each group
q3_18_prop <- q3_18_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(q3_18_prop, aes(x = as.factor(`Q3.18_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
labs(
title = "Q3.18 Impact of Inflation Forecasts Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot pie chart including all participants
q3_18_summary <- q3_18_prop %>%
group_by(`Q3.18_label`) %>%
summarise(total_count = sum(Count), .groups = "drop") %>%
mutate(proportion = total_count / sum(total_count),
`Q3.18_label` = paste0(`Q3.18_label`, " (", round(proportion * 100, 2), " %)"))
ggplot(q3_18_summary, aes(x = "",y = proportion, fill = `Q3.18_label`)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
labs(title = "Q3.18 Impact of Inflation Forecasts Summary Pie Chart",
x = "",
y = "") +
theme_minimal() +
theme(axis.text.x = element_blank())

Q3.19 Response to Inflation Forecasts
How much do you adjust or take action in response to inflation
forecasts (information about future inflation)?
Variable: categorical
Method: contingency table + chi-squared test
Result: Fail to reject the null hypothesis
# Initial Check
summary(as.numeric(rawdata_value$Q3.19))
q3_19_table <- rawdata_value[, c("Q3.19", "group")]
q3_19_contingency <- table(q3_19_table$Q3.19, q3_19_table$group)
print(q3_19_contingency)
# Chi-squared test
chisq.test(q3_19_contingency)
Response to Inflation Forecasts proportion bar plot across different
groups
q3_19_prop <- as.data.frame(q3_19_contingency)
# rename columns
names(q3_19_prop) <- c("Q3.19", "Group", "Count")
# add a labelled column
q3_19_prop <- q3_19_prop %>%
mutate(Q3.19_label = case_when(
Q3.19 == "1" ~ "1-Not at all",
Q3.19 == "2" ~ "2-Rarely",
Q3.19 == "3" ~ "3-Somewhat actively",
Q3.19 == "4" ~ "4-Very actively"
))
# calculate proportions within each group
q3_19_prop <- q3_19_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(q3_19_prop, aes(x = as.factor(`Q3.19_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
labs(
title = "Q3.19 Response to Inflation Forecasts Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot pie chart including all participants
q3_19_summary <- q3_19_prop %>%
group_by(`Q3.19_label`) %>%
summarise(total_count = sum(Count), .groups = "drop") %>%
mutate(proportion = total_count / sum(total_count),
`Q3.19_graph_label` = paste0(`Q3.19_label`, " (", round(proportion * 100, 2), " %)"))
ggplot(q3_19_summary, aes(x = "",y = proportion, fill = `Q3.19_graph_label`)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
labs(title = "Q3.19 Response to Inflation Forecasts Summary Pie Chart",
x = "",
y = "") +
theme_minimal() +
theme(axis.text.x = element_blank())

Actual Survey Analysis
! Qxx.2 Graph Familarity
Have you ever been communicated this type of information
before?
Variable: categorical
Method: Contingency Table + Chi-squared test
recode to yes and no
Result: We can reject the null hypothesis, meaning people are
more or less familiar with certain type of visualisations.
chisq_result <- chisq.test(survey_q2_contingency)
chisq_result$stdres
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
N -1.588275 -0.909674 2.477879 1.397084 -1.459834
Y 1.588275 0.909674 -2.477879 -1.397084 1.459834
Summary Table of proportion of yes and no
yes_per <- survey_q2_contingency[2,]
no_per <- survey_q2_contingency[1,]
familarity_group_total <- colSums(survey_q2_contingency)
yes_prop <- yes_per/familarity_group_total
no_prop <- no_per/familarity_group_total
# convert to data frame
survey_q2_summary <-data.frame(yes_prop, no_prop)
Plot the graph
ggplot(survey_q2, aes(x = q2_recode, fill = group)) +
geom_bar(position = "dodge") +
labs(title = "Have you ever been communicated this type of information before?",
x = "Response",
y = "Count") +
scale_fill_brewer(palette = "Set2") +
theme_minimal()

Qxx.3 Prior Expectation
Does the inflation forecast information provided align with your
expectations?
Variable: categorical
Method: Contingency Table + Chi-squared test
Result: Fail to reject the null hypothesis
# combine data from different groups
survey_q3 <- data.frame()
survey_q3_list <- list("Q4.3","Q6.3", "Q8.3", "Q10.3", "Q12.3")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q3_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q3_value", "group")
survey_q3 <- rbind(survey_q3, temp_table)
}
# Initial Check
summary(as.numeric(survey_q3$q3_value))
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 2.000 2.000 2.476 3.000 5.000
Test the differences between groups
survey_q3_contingency <- table(survey_q3$q3_value, survey_q3$group)
# print the contingency table
print(survey_q3_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 4 3 1 1 4
2 33 39 33 34 31
3 19 15 21 21 20
4 6 1 6 10 3
5 0 1 0 0 3
# Chi-squared test
chisq.test(survey_q3_contingency)
Warning: Chi-squared approximation may be incorrect
Pearson's Chi-squared test
data: survey_q3_contingency
X-squared = 22.933, df = 16, p-value = 0.1155
Plot prior expectation proportion bar plot across different
groups
survey_q3_prop <- as.data.frame(survey_q3_contingency)
# rename columns
names(survey_q3_prop) <- c("Q3.3", "Group", "Count")
# add a labelled column
survey_q3_prop <- survey_q3_prop %>%
mutate(Q3.3_label = case_when(
Q3.3 == "1" ~ "1-Strongly aligns",
Q3.3 == "2" ~ "2-Somewhat aligns",
Q3.3 == "3" ~ "3-Neutral",
Q3.3 == "4" ~ "4-Somewhat does not align",
Q3.3 == "5" ~ "5-Does not align at all",
))
# calculate proportions within each group
survey_q3_prop <- survey_q3_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_q3_prop, aes(x = as.factor(`Q3.3_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
labs(
title = "Q3.3 Prior Expectation Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot pie chart including all participants
survey_q3_summary <- survey_q3_prop %>%
group_by(`Q3.3_label`) %>%
summarise(total_count = sum(Count), .groups = "drop") %>%
mutate(proportion = total_count / sum(total_count),
`Q3.3_graph_label` = paste0(`Q3.3_label`, " (", round(proportion * 100, 2), " %)"))
ggplot(survey_q3_summary, aes(x = "",y = proportion, fill = `Q3.3_graph_label`)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
labs(title = "Q3.3 Prior Expectation Summary Pie Chart",
x = "",
y = "") +
theme_minimal() +
theme(axis.text.x = element_blank())

Qxx.4 Confliction with Prior Expectation
How does the inflation forecast conflict with your
expectations?
Variable: categorical
Method: calculate total number of people who think the forecast is not
aligned with their expectation
Result: Among people who think the forecast is not aligned with
their expectation, 90% percent of respondents thinks the forecast is
lower than what they expected.
# Check the number of people answered this question
n_not_align <- sum(survey_q3_summary$total_count[4:5])
# Combine data from different groups
survey_q4 <- data.frame()
survey_q4_list <- list("Q4.4","Q6.4", "Q8.4", "Q10.4", "Q12.4")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q4_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q4_value", "group")
survey_q4 <- rbind(survey_q4, temp_table)
}
survey_q4 <- survey_q4[!is.na(survey_q4$q4_value), ]
survey_q4_contingency <- table(survey_q4$q4_value, survey_q4$group)
# print the contingency table
print(survey_q4_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 1 0 2 0 0
2 5 2 4 10 6
Plot confliction with prior expectation proportion bar plot across
different groups
survey_q4_prop <- as.data.frame(survey_q4_contingency)
# rename columns
names(survey_q4_prop) <- c("Q4.4", "Group", "Count")
# add a labelled column
survey_q4_prop <- survey_q4_prop %>%
mutate(Q4.4_label = case_when(
Q4.4 == "1" ~ "1-Higher than what I expected",
Q4.4 == "2" ~ "2-Lower than what I expected"
))
# calculate proportions within each group
survey_q4_prop <- survey_q4_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_q4_prop, aes(x = as.factor(`Q4.4_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
labs(
title = "Q4.4 Confliction with Prior Expectation Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot pie chart including all participants
Qxx.6 Probability of exactly 2.6%
what do you think is the probability of inflation being exactly
2.6%?
Definitive Correct Answer
descending order
Variable: categorical
Method: contingency table & proportion test
Result: There is no statistical difference in terms of correctly
answering the probability of inflation being exactly 2.6%.
# combine data from different groups
survey_q6 <- data.frame()
survey_q6_list <- list("Q4.6","Q6.6", "Q8.6", "Q10.6", "Q12.6")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q6_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q6_value", "group")
survey_q6 <- rbind(survey_q6, temp_table)
}
survey_q6$q6_value <- as.numeric(survey_q6$q6_value)
survey_q6_contingency <- table(survey_q6$q6_value, survey_q6$group)
print(survey_q6_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 0 0 1 0 0
2 4 5 10 8 5
3 18 12 3 6 5
4 5 4 3 3 2
5 20 5 20 22 25
6 7 17 10 13 12
7 8 16 14 14 12
# whether one proportion differs across groups
less_than_1_per <- survey_q6_contingency[7,]
survey_q6_group_total <- colSums(survey_q6_contingency)
prop.test(less_than_1_per, survey_q6_group_total)
5-sample test for equality of proportions without continuity
correction
data: less_than_1_per out of survey_q6_group_total
X-squared = 4.0132, df = 4, p-value = 0.4042
alternative hypothesis: two.sided
sample estimates:
prop 1 prop 2 prop 3 prop 4 prop 5
0.1290323 0.2711864 0.2295082 0.2121212 0.1967213
Plot probability of exactly 2.6% proportion bar plot across different
groups
survey_q6_prop <- as.data.frame(survey_q6_contingency)
# rename columns
names(survey_q6_prop) <- c("Qxx.6", "Group", "Count")
# add a labelled column
survey_q6_prop <- survey_q6_prop %>%
mutate(Qxx.6_label = case_when(
Qxx.6 == "1" ~ "1->99%",
Qxx.6 == "2" ~ "2-around 80%",
Qxx.6 == "3" ~ "3-around 60%",
Qxx.6 == "4" ~ "4-around 50%",
Qxx.6 == "5" ~ "5-around 30%",
Qxx.6 == "6" ~ "6-around 20%",
Qxx.6 == "7" ~ "7-<1%"
))
# calculate proportions within each group
survey_q6_prop <- survey_q6_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_q6_prop, aes(x = as.factor(`Qxx.6_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
# facet_wrap(~Group)+
labs(
title = "Qxx.6 Probability of exactly 2.6% Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot the histogram including all participants
# histogram including all participants
ggplot(survey_q6, aes(x = q6_value)) +
geom_histogram(binwidth = 1, fill = "steelblue", color = "white") +
labs(title = "Qxx.6 Probability of exactly 2.6% Histogram",
x = "Response",
y = "Count") +
scale_x_continuous(breaks = seq(0, max(survey_q6$q6_value, na.rm = TRUE), by = 1)) +
theme_minimal()

Plot pie chart including all participants
survey_q6_summary <- survey_q6_prop %>%
group_by(`Q6.6_label`) %>%
summarise(total_count = sum(Count), .groups = "drop") %>%
mutate(proportion = total_count / sum(total_count),
`Q6.6_graph_label` = paste0(`Q6.6_label`, " (", round(proportion * 100, 2), " %)"))
ggplot(survey_q6_summary, aes(x = "",y = proportion, fill = `Q6.6_graph_label`)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
labs(title = "Qxx.6 Probability of exactly 2.6% Summary Pie Chart",
x = "",
y = "") +
theme_minimal() +
theme(axis.text.x = element_blank())

! Qxx.7 Probability of between 1.9% and 3.3%
what do you think is the probability of inflation being between 1.9%
and 3.3%?
Definitive Correct Answer
descending order
Method: contingency table & proportion test
Result: There is statistical difference in control group in
terms of the proportion of the correct answer of how people think the
probability of inflation being between 1.9% and 3.3% is.
# combine data from different groups
survey_q7 <- data.frame()
survey_q7_list <- list("Q4.7","Q6.7", "Q8.7", "Q10.7", "Q12.7")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q7_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q7_value", "group")
survey_q7 <- rbind(survey_q7, temp_table)
}
survey_q7$q7_value <- as.numeric(survey_q7$q7_value)
Test the proportion of correct answer
survey_q7_contingency <- table(survey_q7$q7_value, survey_q7$group)
# print the contingency table
print(survey_q7_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 10 0 0 3 1
2 23 7 11 9 9
3 17 18 11 14 7
4 9 13 7 8 10
5 3 18 27 25 29
6 0 3 5 7 4
7 0 0 0 0 1
# correct answer
survey_q7_correct <- survey_q7_contingency[5,]
survey_q7_group_total <- colSums(survey_q7_contingency)
prop.test(survey_q7_correct, survey_q7_group_total)
5-sample test for equality of proportions without continuity correction
data: survey_q7_correct out of survey_q7_group_total
X-squared = 32.443, df = 4, p-value = 1.553e-06
alternative hypothesis: two.sided
sample estimates:
prop 1 prop 2 prop 3 prop 4 prop 5
0.0483871 0.3050847 0.4426230 0.3787879 0.4754098
# pairwise proportion test
pairwise.prop.test(
x = survey_q7_contingency[5, ],
n = colSums(survey_q7_contingency),
p.adjust.method = "bonferroni" # or "holm", "BH"
)
Pairwise comparisons using Pairwise comparison of proportions
data: survey_q7_contingency[5, ] out of colSums(survey_q7_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice
1-errorbar 0.00489 - - -
2-shadedbar 1.1e-05 1.00000 - -
3-fanchartslice 0.00017 1.00000 1.00000 -
4-bellcurve 2.1e-06 0.84724 1.00000 1.00000
P value adjustment method: bonferroni
Plot probability of between 1.9% and 3.3% proportion bar plot across
different groups
survey_q7_prop <- as.data.frame(survey_q7_contingency)
# rename columns
names(survey_q7_prop) <- c("Qxx.7", "Group", "Count")
# add a labelled column
survey_q7_prop <- survey_q7_prop %>%
mutate(Qxx.7_label = case_when(
Qxx.7 == "1" ~ "1->99%",
Qxx.7 == "2" ~ "2-around 80%",
Qxx.7 == "3" ~ "3-around 60%",
Qxx.7 == "4" ~ "4-around 50%",
Qxx.7 == "5" ~ "5-around 30%",
Qxx.7 == "6" ~ "6-around 20%",
Qxx.7 == "7" ~ "7-<1%"
))
# calculate proportions within each group
survey_q7_prop <- survey_q7_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_q7_prop, aes(x = as.factor(`Qxx.7_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
# facet_wrap(~Group)+
labs(
title = "Qxx.7 Probability of between 1.9% and 3.3% Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot the histogram including all participants
# histogram including all participants
ggplot(survey_q7, aes(x = q7_value)) +
geom_histogram(binwidth = 1, fill = "steelblue", color = "white") +
# facet_wrap(~ group) +
labs(title = "Qxx.7 Probability of between 1.9% and 3.3% Histogram",
x = "Qxx.7",
y = "Count") +
scale_x_continuous(breaks = seq(0, max(survey_q7$q7_value, na.rm = TRUE), by = 1)) +
theme_minimal()

Qxx.8 Probability of between 3.3% and 5.6%
what do you think is the probability of inflation being between 3.3%
and 5.6%?
Definitive Correct Answer
descending order
Method: contingency table & proportion test
Result: The control group and the error bar group has shown
statistical difference.
# combine data from different groups
survey_q8 <- data.frame()
survey_q8_list <- list("Q4.8","Q6.8", "Q8.8", "Q10.8", "Q12.8")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q8_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q8_value", "group")
survey_q8 <- rbind(survey_q8, temp_table)
}
survey_q8$q8_value <- as.numeric(survey_q8$q8_value)
contingency table
survey_q8_contingency <- table(survey_q8$q8_value, survey_q8$group)
# print the contingency table
print(survey_q8_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 1 0 1 1 1
2 3 2 3 2 7
3 13 4 5 10 5
4 5 5 9 6 2
5 14 34 29 23 28
6 18 13 11 22 12
7 8 1 3 2 6
# correct answer
survey_q8_correct <- survey_q8_contingency[5,]
survey_q8_group_total <- colSums(survey_q8_contingency)
prop.test(survey_q8_correct, survey_q8_group_total)
5-sample test for equality of proportions without continuity correction
data: survey_q8_correct out of survey_q8_group_total
X-squared = 18.077, df = 4, p-value = 0.001192
alternative hypothesis: two.sided
sample estimates:
prop 1 prop 2 prop 3 prop 4 prop 5
0.2258065 0.5762712 0.4754098 0.3484848 0.4590164
# pairwise proportion test
pairwise.prop.test(
x = survey_q8_contingency[5, ],
n = colSums(survey_q8_contingency),
p.adjust.method = "bonferroni" # or "holm", "BH"
)
Pairwise comparisons using Pairwise comparison of proportions
data: survey_q8_contingency[5, ] out of colSums(survey_q8_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice
1-errorbar 0.0017 - - -
2-shadedbar 0.0666 1.0000 - -
3-fanchartslice 1.0000 0.1766 1.0000 -
4-bellcurve 0.1118 1.0000 1.0000 1.0000
P value adjustment method: bonferroni
Plot probability of between 3.3% and 5.6% proportion bar plot across
different groups
survey_q8_prop <- as.data.frame(survey_q8_contingency)
# rename columns
names(survey_q8_prop) <- c("Qxx.8", "Group", "Count")
# add a labelled column
survey_q8_prop <- survey_q8_prop %>%
mutate(Qxx.8_label = case_when(
Qxx.8 == "1" ~ "1->99%",
Qxx.8 == "2" ~ "2-around 80%",
Qxx.8 == "3" ~ "3-around 60%",
Qxx.8 == "4" ~ "4-around 50%",
Qxx.8 == "5" ~ "5-around 30%",
Qxx.8 == "6" ~ "6-around 20%",
Qxx.8 == "7" ~ "7-<1%"
))
# calculate proportions within each group
survey_q8_prop <- survey_q8_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_q8_prop, aes(x = as.factor(`Qxx.8_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
# facet_wrap(~Group)+
labs(
title = "Qxx.8 Probability of between 3.3% and 5.6% Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot the histogram including all participants
# histogram including all participants
ggplot(survey_q8, aes(x = q8_value)) +
geom_histogram(binwidth = 1, fill = "steelblue", color = "white") +
# facet_wrap(~ group) +
labs(title = "Qxx.8 Probability of between 3.3% and 5.6% Histogram",
x = "Qxx.8",
y = "Count") +
scale_x_continuous(breaks = seq(0, max(survey_q8$q8_value, na.rm = TRUE), by = 1)) +
theme_minimal()

! Qxx.10 Probability of ending outside the range
Based on the inflation forecast provided, what do you think is the
probability of inflation ending up outside of the range from -0.4% to
5.6%?
Definitive Correct Answer (varied between group)
descending order
Variable: categorical
Method: calculate the proportion for each group + proportion test
Result: Control group perform significant worse than other
groups.
# pairwise proportion test
pairwise.prop.test(
x = setNames(survey_q10$correct, survey_q10$group),
n = setNames(survey_q10$total, survey_q10$group),
p.adjust.method = "bonferroni" # or "holm", "BH"
)
Pairwise comparisons using Pairwise comparison of proportions
data: setNames(survey_q10$correct, survey_q10$group) out of setNames(survey_q10$total, survey_q10$group)
controlled errorbar shadedbar fanchartslice
errorbar 5.3e-05 - - -
shadedbar 0.0135 1.0000 - -
fanchartslice 0.0039 1.0000 1.0000 -
bellcurve 2.6e-07 1.0000 0.1781 0.3392
P value adjustment method: bonferroni
ggplot(survey_q10, aes(x = group, y = prop)) +
geom_bar(stat = "identity", fill = "steelblue") +
geom_text(aes(label = scales::percent(prop, accuracy = 1)), vjust = -0.5) +
labs(title = "Qxx.10 Probability of ending outside the range correct answer rate",
x = "Group",
y = "Proportion") +
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()

Plot distribution for each individual group
ggplot(controlled_group, aes(x = as.numeric(as.character(Q4.10)))) +
geom_histogram(binwidth = 1, fill = "steelblue", color = "white") +
scale_y_continuous(
limits = c(0, 50), # force y from 0 up to 60
breaks = seq(0, 50, by=10) # ticks at 0, 10, 20, …, 60
) +
geom_text(aes(label = ..count..), stat = "count", vjust = -0.5) +
labs(
title = "Controlled Group: Distribution of Q4.10 Responses",
x = "Q4.10 (numeric)",
y = "Count"
) +
theme_minimal()

Qxx.11 Probability of higher than 6%
Based on the inflation forecast provided, what do you think is the
probability of inflation ending up higher than 6%?
Definitive Correct Answer - 3
variable: categorical
Method: contingency table & proportion test
Result: The bell curve and the control group has shown
significant difference. The majority people think the probability is
extremely low (less than 1%).
Test the proportion of correct answer
survey_q11_contingency <- table(survey_q11$q11_value, survey_q11$group)
# print the contingency table
print(survey_q11_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 1 4 1 0 4
2 13 12 9 10 9
3 13 21 24 24 29
4 33 15 24 30 16
5 2 7 3 2 3
survey_q11_correct <- survey_q11_contingency[3,]
survey_q11_group_total <- colSums(survey_q11_contingency)
prop.test(survey_q11_correct, survey_q11_group_total)
5-sample test for equality of proportions without continuity
correction
data: survey_q11_correct out of survey_q11_group_total
X-squared = 9.9199, df = 4, p-value = 0.0418
alternative hypothesis: two.sided
sample estimates:
prop 1 prop 2 prop 3 prop 4 prop 5
0.2096774 0.3559322 0.3934426 0.3636364 0.4754098
Post-hoc test
pairwise.prop.test(
x = survey_q11_contingency[3, ],
n = colSums(survey_q11_contingency),
p.adjust.method = "bonferroni" # or "holm", "BH"
)
Pairwise comparisons using Pairwise comparison of proportions
data: survey_q11_contingency[3, ] out of colSums(survey_q11_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice
1-errorbar 1.000 - - -
2-shadedbar 0.428 1.000 - -
3-fanchartslice 0.845 1.000 1.000 -
4-bellcurve 0.035 1.000 1.000 1.000
P value adjustment method: bonferroni
Plot probability of higher than 6% proportion bar plot across
different groups
survey_q11_prop <- as.data.frame(survey_q11_contingency)
# rename columns
names(survey_q11_prop) <- c("Qxx.11", "Group", "Count")
# add a labelled column
survey_q11_prop <- survey_q11_prop %>%
mutate(Qxx.11_label = case_when(
Qxx.11 == "1" ~ "1-More than 20%",
Qxx.11 == "2" ~ "3-5-10%",
Qxx.11 == "3" ~ "4-1-5%",
Qxx.11 == "4" ~ "5-Less than 1%",
Qxx.11 == "5" ~ "2-10-20%"
))
# calculate proportions within each group
survey_q11_prop <- survey_q11_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_q11_prop, aes(x = as.factor(`Qxx.11_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
# facet_wrap(~Group)+
labs(
title = "Qxx.11 Probability of higher than 6% Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot the histogram including all participants
Qxx.12 Probability of higher than 3%
Based on the inflation forecast provided, what do you think is the
probability of inflation ending up higher than 3%?
Definitive Correct Answer - 1
variable: categorical
Method: contingency table & proportion test
Result: There is no statistical difference and the majority
people didn’t get the answer right.
# combine data from different groups
survey_q12 <- data.frame()
survey_q12_list <- list("Q4.12","Q6.12", "Q8.12", "Q10.12", "Q12.12")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q12_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q12_value", "group")
survey_q12 <- rbind(survey_q12, temp_table)
}
survey_q12$q12_value <- as.numeric(survey_q12$q12_value)
Test the proportion of correct answer
survey_q12_contingency <- table(survey_q12$q12_value, survey_q12$group)
# print the contingency table
print(survey_q12_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 3 3 2 5 4
2 15 14 19 12 13
3 19 18 26 29 22
4 11 7 11 12 13
5 14 17 3 8 9
survey_q12_correct <- survey_q12_contingency[2,]
survey_q12_group_total <- colSums(survey_q12_contingency)
prop.test(survey_q12_correct, survey_q12_group_total)
5-sample test for equality of proportions without continuity
correction
data: survey_q12_correct out of survey_q12_group_total
X-squared = 3.1893, df = 4, p-value = 0.5267
alternative hypothesis: two.sided
sample estimates:
prop 1 prop 2 prop 3 prop 4 prop 5
0.2419355 0.2372881 0.3114754 0.1818182 0.2131148
Plot probability of higher than 3% proportion bar plot across
different groups
survey_q12_prop <- as.data.frame(survey_q12_contingency)
# rename columns
names(survey_q12_prop) <- c("Qxx.12", "Group", "Count")
# add a labelled column
survey_q12_prop <- survey_q12_prop %>%
mutate(Qxx.12_label = case_when(
Qxx.12 == "1" ~ "1-More than 60%",
Qxx.12 == "2" ~ "3-40-50%",
Qxx.12 == "3" ~ "4-30-40%",
Qxx.12 == "4" ~ "5-Less than 30%",
Qxx.12 == "5" ~ "2-50-60%"
))
# calculate proportions within each group
survey_q12_prop <- survey_q12_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_q12_prop, aes(x = as.factor(`Qxx.12_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
# facet_wrap(~Group)+
labs(
title = "Qxx.12 Probability of higher than 3% Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot the histogram including all participants
# force order for graph
survey_q12 <- survey_q12 %>%
mutate(
q12_value_re = factor(
q12_value,
levels = c(1, 5, 2, 3, 4)
)
)
# histogram including all participants
ggplot(survey_q12, aes(x = q12_value_re)) +
geom_bar(fill = "steelblue", color = "white") +
labs(
title = "Qxx.12 Responses (forced 1-5-2-3-4 order)",
x = "Qxx.12",
y = "Count"
) +
theme_minimal()

! Qxx.14 Probability of higher than 2% target
To keep inflation low and stable, Government sets an inflation target
of 2%. Based on the inflation forecast provided, what do you think is
the probability of inflation exceeding 2%?
Definitive Correct Answer - 3
variable: categorical
Method: contingency table & proportion test
Result: Control group is significant different from error Bar
group and bell curve group; Error bar group has shown statistical
difference compared to fan chart slice. 44% of total respondents can
understand the probability of inflation being higher than 6%
correctly.
# combine data from different groups
survey_q14 <- data.frame()
survey_q14_list <- list("Q4.14","Q6.14", "Q8.14", "Q10.14", "Q12.14")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q14_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q14_value", "group")
survey_q14 <- rbind(survey_q14, temp_table)
}
survey_q14$q14_value <- as.numeric(survey_q14$q14_value)
Test the proportion of correct answer
survey_q14_correct <- survey_q14_contingency[3,]
survey_q14_group_total <- colSums(survey_q14_contingency)
prop.test(survey_q14_correct, survey_q14_group_total)
5-sample test for equality of proportions without continuity
correction
data: survey_q14_correct out of survey_q14_group_total
X-squared = 21.144, df = 4, p-value = 0.0002965
alternative hypothesis: two.sided
sample estimates:
prop 1 prop 2 prop 3 prop 4 prop 5
0.2580645 0.6101695 0.4754098 0.3333333 0.5409836
Pairwise proportion test
pairwise.prop.test(
x = survey_q14_contingency[3, ],
n = colSums(survey_q14_contingency),
p.adjust.method = "holm" # or "holm", "BH"
)
Pairwise comparisons using Pairwise comparison of proportions
data: survey_q14_contingency[3, ] out of colSums(survey_q14_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice
1-errorbar 0.0019 - - -
2-shadedbar 0.1443 0.7772 - -
3-fanchartslice 1.0000 0.0281 0.7344 -
4-bellcurve 0.0227 1.0000 1.0000 0.1754
P value adjustment method: holm
Plot probability of higher than 2% target proportion bar plot across
different groups
survey_q14_prop <- as.data.frame(survey_q14_contingency)
# rename columns
names(survey_q14_prop) <- c("Qxx.14", "Group", "Count")
# add a labelled column
survey_q14_prop <- survey_q14_prop %>%
mutate(Qxx.14_label = case_when(
Qxx.14 == "1" ~ "1->99%",
Qxx.14 == "2" ~ "2-around 80%",
Qxx.14 == "3" ~ "3-around 60%",
Qxx.14 == "4" ~ "4-around 50%",
Qxx.14 == "5" ~ "5-around 30%",
Qxx.14 == "6" ~ "6-around 20%",
Qxx.14 == "7" ~ "7-<1%"
))
# calculate proportions within each group
survey_q14_prop <- survey_q14_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_q14_prop, aes(x = as.factor(`Qxx.14_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
# facet_wrap(~Group)+
labs(
title = "Qxx.14 Probability of higher than 2% target Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot the histogram including all participants
# histogram including all participants
ggplot(survey_q14, aes(x = q14_value)) +
geom_histogram(binwidth = 1, fill = "steelblue", color = "white") +
# facet_wrap(~ group) +
labs(title = "Qxx.14 Probability of higher than 2% target Histogram",
x = "Qxx.14",
y = "Count") +
scale_x_continuous(breaks = seq(0, max(survey_q14$q14_value, na.rm = TRUE), by = 1)) +
theme_minimal()

Qxx.15 Deviation from central estimate
Based on the inflation forecast provided, do you think there is a
higher risk of inflation in 2026Q2 exceeding the central estimate or of
being less than this central estimate?
Definitive Correct Answer - 3
variable: categorical
Method: contingency table & proportion test
Result: The control group shows significant difference compared
to the shaded bar group in terms of the correctly choosing understanding
the risk is equal. Among all participants, only around 8% respondents
think there is downside risk. The largest proportion (48%) of
participants believe there is upside risk.
# combine data from different groups
survey_q15 <- data.frame()
survey_q15_list <- list("Q4.15","Q6.15", "Q8.15", "Q10.15", "Q12.15")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q15_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q15_value", "group")
survey_q15 <- rbind(survey_q15, temp_table)
}
survey_q15$q15_value <- as.numeric(survey_q15$q15_value)
Contingency table
survey_q15_correct <- survey_q15_contingency[3,]
survey_q15_group_total <- colSums(survey_q15_contingency)
prop.test(survey_q15_correct, survey_q15_group_total)
5-sample test for equality of proportions without continuity
correction
data: survey_q15_correct out of survey_q15_group_total
X-squared = 14.519, df = 4, p-value = 0.005811
alternative hypothesis: two.sided
sample estimates:
prop 1 prop 2 prop 3 prop 4 prop 5
0.2741935 0.4576271 0.5901639 0.5000000 0.3770492
Pairwise proportion test
pairwise.prop.test(
x = survey_q15_contingency[3, ],
n = colSums(survey_q15_contingency),
p.adjust.method = "bonferroni" # or "holm", "BH"
)
Pairwise comparisons using Pairwise comparison of proportions
data: survey_q15_contingency[3, ] out of colSums(survey_q15_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice
1-errorbar 0.5644 - - -
2-shadedbar 0.0079 1.0000 - -
3-fanchartslice 0.1487 1.0000 1.0000 -
4-bellcurve 1.0000 1.0000 0.2970 1.0000
P value adjustment method: bonferroni
Plot proportion bar plot across different groups
survey_q15_prop <- as.data.frame(survey_q15_contingency)
# rename columns
names(survey_q15_prop) <- c("Qxx.15", "Group", "Count")
# add a labelled column
survey_q15_prop <- survey_q15_prop %>%
mutate(Qxx.15_label = case_when(
Qxx.15 == "1" ~ "1-bigger upside risk",
Qxx.15 == "2" ~ "2-bigger downside risk",
Qxx.15 == "3" ~ "3-equal risks on both sides"
))
# calculate proportions within each group
survey_q15_prop <- survey_q15_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_q15_prop, aes(x = as.factor(`Qxx.15_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
# facet_wrap(~Group)+
labs(
title = "Qxx.15 Answer Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot the histogram including all participants
Qxx.17 Self-reported likelihood of exactly 2.6%
How likely do you think it is that the inflation will be exactly
2.6%?
ascending value-increasing likelihood
Variable: treat as continuous
Method: Kruskal-Wallis test
Result: Fail to reject the null hypothesis. The overall
distribution is skewed towards unlikely.
# combine data from different groups
survey_q17 <- data.frame()
survey_q17_list <- list("Q4.17_1","Q6.17_1", "Q8.17_1", "Q10.17_1", "Q12.17_1")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q17_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q17_value", "group")
survey_q17 <- rbind(survey_q17, temp_table)
}
survey_q17$q17_value <- as.numeric(survey_q17$q17_value)
KW test
# check normality --> the data is not normally distributed
# shapiro.test(survey_q17$q17_value)
# run Kruskal-Wallis test
kruskal_test <- kruskal.test(q17_value ~ group, data = survey_q17)
print(kruskal_test)
Kruskal-Wallis rank sum test
data: q17_value by group
Kruskal-Wallis chi-squared = 1.4881, df = 4, p-value = 0.8287
Plot the distribution of different groups
# add labels
likelihood_labels = c(
"9" = "Exceptionally unlikely",
"10" = "Very unlikely",
"11" = "Quite unlikely",
"12" = "Fifty-fifty",
"13" = "Quite likely",
"14" = "Very likely",
"15" = "Virtually certain"
)
# histogram including all participants
ggplot(survey_q17, aes(x = q17_value)) +
geom_histogram(binwidth = 1, fill = "steelblue", color = "white") +
# facet_wrap(~ group) +
labs(title = "Qxx.17 Self-reported likelihood of exactly 2.6% distribution",
x = "Qxx.17",
y = "Count") +
scale_x_continuous(breaks = as.numeric(names(likelihood_labels)),
labels = likelihood_labels) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Grouped bar-style histogram
ggplot(survey_q17, aes(x = factor(q17_value), fill = factor(group))) +
geom_bar(position = "dodge") +
# facet_wrap(~ group) +
# add labels
scale_x_discrete(labels=likelihood_labels) +
labs(
title = "Qxx.17 Self-reported likelihood of exactly 2.6% distribution by group",
x = "Qxx.17 Response",
y = "Count",
fill = "Group"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Qxx.21 Self-reported likelihood of inflation being between 1.9% and
3.3%
How likely do you think it is that the inflation will be between 1.9%
and 3.3%?
ascending value-increasing likelihood
Variable: treat as continuous
Method: Kruskal-Wallis test
Result: Fail to reject the null hypothesis. The majority of
respondents think it’s quite likely.
# combine data from different groups
survey_q21 <- data.frame()
survey_q21_list <- list("Q4.21_1","Q6.21_1", "Q8.21_1", "Q10.21_1", "Q12.21_1")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q21_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q21_value", "group")
survey_q21 <- rbind(survey_q21, temp_table)
}
survey_q21$q21_value <- as.numeric(survey_q21$q21_value)
KW test
# check normality --> the data is not normally distributed
# shapiro.test(survey_q21$q21_value)
# run Kruskal-Wallis test
kruskal_test <- kruskal.test(q21_value ~ group, data = survey_q21)
print(kruskal_test)
Kruskal-Wallis rank sum test
data: q21_value by group
Kruskal-Wallis chi-squared = 8.6617, df = 4, p-value = 0.07013
Plot the distribution of different groups
# add labels
likelihood_labels = c(
"9" = "Exceptionally unlikely",
"10" = "Very unlikely",
"11" = "Quite unlikely",
"12" = "Fifty-fifty",
"13" = "Quite likely",
"14" = "Very likely",
"15" = "Virtually certain"
)
# Grouped bar-style histogram
ggplot(survey_q21, aes(x = factor(q21_value), fill = factor(group))) +
geom_bar(position = "dodge") +
# facet_wrap(~ group) +
# add labels
scale_x_discrete(labels=likelihood_labels) +
labs(
title = "Qxx.21 Self-reported likelihood of inflation being between 1.9% and 3.3% distribution by group",
x = "Qxx.21 Response",
y = "Count",
fill = "Group"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot bar chart including all participants
! Qxx.22 Self-reported likelihood of inflation being between 3.3%
and 5.6%
How likely do you think it is that the inflation will be between 3.3%
and 5.6%?
ascending value-increasing likelihood
Variable: treat as continuous
Method: Kruskal-Wallis test
Result: The distribution of shaded bar group and bell curve show
statistical difference. Near half of the respondents think it’s quite
unlikely.
# combine data from different groups
survey_q22 <- data.frame()
survey_q22_list <- list("Q4.22_1","Q6.22_1", "Q8.22_1", "Q10.22_1", "Q12.22_1")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q22_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q22_value", "group")
survey_q22 <- rbind(survey_q22, temp_table)
}
survey_q22$q22_value <- as.numeric(survey_q22$q22_value)
KW test
dunnTest(q22_value ~ group, data = survey_q22, method = "bonferroni")
Warning: group was coerced to a factor.Dunn (1964) Kruskal-Wallis multiple comparison
p-values adjusted with the Bonferroni method.
Plot the distribution of different groups
# Grouped bar-style histogram
ggplot(survey_q22, aes(x = factor(q22_value), fill = factor(group))) +
geom_bar(position = "dodge") +
facet_wrap(~ group) +
# add labels
scale_x_discrete(labels=likelihood_labels) +
labs(
title = "Qxx.22 Self-reported likelihood of inflation being between 3.3% and 5.6% distribution by group",
x = "Qxx.22 Response",
y = "Count",
fill = "Group"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot bar chart including all participants
# histogram including all participants
ggplot(survey_q22, aes(x = q22_value)) +
geom_histogram(binwidth = 1, fill = "steelblue", color = "white") +
# facet_wrap(~ group) +
labs(title = "Qxx.22 Self-reported likelihood of inflation being between 3.3% and 5.6% distribution",
x = "Qxx.22",
y = "Count") +
scale_x_continuous(breaks = as.numeric(names(likelihood_labels)),
labels = likelihood_labels) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Qxx.23 Self-reported likelihood of inflation being higher than
3%
How likely do you think it is that the inflation will be higher than
3%?
ascending value-increasing likelihood
Variable: treat as continuous
Method: Kruskal-Wallis test
Result: Fail to reject the null hypothesis. The majority of
respondents think it’s quite unlikely, but there is no significant
difference.
# combine data from different groups
survey_q23 <- data.frame()
survey_q23_list <- list("Q4.23_1","Q6.23_1", "Q8.23_1", "Q10.23_1", "Q12.23_1")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q23_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q23_value", "group")
survey_q23 <- rbind(survey_q23, temp_table)
}
survey_q23$q23_value <- as.numeric(survey_q23$q23_value)
KW test
# check normality --> the data is not normally distributed
# shapiro.test(survey_q23$q23_value)
# run Kruskal-Wallis test
kruskal_test <- kruskal.test(q23_value ~ group, data = survey_q23)
print(kruskal_test)
Kruskal-Wallis rank sum test
data: q23_value by group
Kruskal-Wallis chi-squared = 3.1999, df = 4, p-value = 0.525
Plot the distribution of different groups
# Grouped bar-style histogram
ggplot(survey_q23, aes(x = factor(q23_value), fill = factor(group))) +
geom_bar(position = "dodge") +
# facet_wrap(~ group) +
# add labels
scale_x_discrete(labels=likelihood_labels) +
labs(
title = "Qxx.23 Self-reported likelihood of inflation being higher than 3% distribution by group",
x = "Qxx.23 Response",
y = "Count",
fill = "Group"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot bar chart including all participants
# histogram including all participants
ggplot(survey_q23, aes(x = q23_value)) +
geom_histogram(binwidth = 1, fill = "steelblue", color = "white") +
# facet_wrap(~ group) +
labs(title = "Qxx.23 Self-reported likelihood of inflation being higher than 3% distribution",
x = "Qxx.23",
y = "Count") +
scale_x_continuous(breaks = as.numeric(names(likelihood_labels)),
labels = likelihood_labels) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Qxx.26 Accuracy of central estimate
On a scale of 1 to 10, where 1 means not accurate at all and 10 means
very accurate, how accurate do you think the central estimate in the
graph is?
1-Not accurate at all; 10-Very accurate
Variable: continuous
Method: ANNOVA test or KW test (depends on whether it’s normally
distributed)
Result: Fail to reject the null hypothesis.
# combine data from different groups
survey_q26 <- data.frame()
survey_q26_list <- list("Q4.26_1","Q6.26_1", "Q8.26_1", "Q10.26_1", "Q12.26_1")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q26_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q26_value", "group")
survey_q26 <- rbind(survey_q26, temp_table)
}
survey_q26$q26_value <- as.numeric(survey_q26$q26_value)
Statistical test
# Initial Check
summary(survey_q26$q26_value)
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.000 6.000 7.000 6.421 7.000 10.000
# check normality --> the data is not normally distributed
# shapiro.test(survey_q26$q26_value)
# run Kruskal-Wallis test
kruskal_test <- kruskal.test(q26_value ~ group, data = survey_q26)
print(kruskal_test)
Kruskal-Wallis rank sum test
data: q26_value by group
Kruskal-Wallis chi-squared = 1.3483, df = 4, p-value = 0.8531
Summary statistics
# Summary statistics
survey_q26_summary <- survey_q26 %>%
group_by(group) %>%
summarise(
mean = mean(q26_value, na.rm = TRUE),
median = median(q26_value, na.rm = TRUE),
sd = sd(q26_value, na.rm = TRUE)
)
Plot the distribution of different groups
# Grouped bar-style histogram\
ggplot(survey_q26, aes(x = factor(q26_value), fill = factor(group))) +
geom_bar(position = "dodge") +
# facet_wrap(~ group) +
labs(
title = "Qxx.26 Accuracy of central estimate distribution by group",
x = "Qxx.26 Response",
y = "Count",
fill = "Group"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Qxx.27 Certainty of central estimate
On a scale of 1 to 10, where 1 means very uncertain and 10 means very
certain, how certain or uncertain do you think the inflation forecast
for 2026 Q2 is?
1-Very uncertain; 10-Very certain
Variable: continuous
Method: ANNOVA test or KW test (depends on whether it’s normally
distributed)
Result: Fail to reject the null hypothesis.
# combine data from different groups
survey_q27 <- data.frame()
survey_q27_list <- list("Q4.27_1","Q6.27_1", "Q8.27_1", "Q10.27_1", "Q12.27_1")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q27_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q27_value", "group")
survey_q27 <- rbind(survey_q27, temp_table)
}
survey_q27$q27_value <- as.numeric(survey_q27$q27_value)
Statistical test
# Initial Check
# summary(survey_q27$q27_value)
# check normality --> the data is not normally distributed
# shapiro.test(survey_q27$q27_value)
# run Kruskal-Wallis test
kruskal_test <- kruskal.test(q27_value ~ group, data = survey_q27)
print(kruskal_test)
Summary statistics
# Summary statistics
survey_q27_summary <- survey_q27 %>%
group_by(group) %>%
summarise(
mean = mean(q27_value, na.rm = TRUE),
median = median(q27_value, na.rm = TRUE),
sd = sd(q27_value, na.rm = TRUE)
)
Plot the distribution of different groups
# Grouped bar-style histogram
ggplot(survey_q27, aes(x = factor(q27_value), fill = factor(group))) +
geom_bar(position = "dodge") +
facet_wrap(~ group) +
labs(
title = "Qxx.27 The distribution of ceartainty/uncertainty of the central estimate by group",
x = "Qxx.27 Response",
y = "Count",
fill = "Group"
) +
theme_minimal()
Qxx.29 Representativeness of the uncertainty
On a scale of 1 to 10, where 1 means not representative at all and 10
means very representative, how representative do you think the
uncertainty being communicated is (i.e., how well the given information
reflects the true variability or uncertainty of the forecast?)
1-Not representative at all; 10-Very representative
Variable: continuous
Method: ANNOVA test or KW test (depends on whether it’s normally
distributed)
Result: Fail to reject the null hypothesis.
# combine data from different groups
survey_q29 <- data.frame()
survey_q29_list <- list("Q4.29_1","Q6.29_1", "Q8.29_1", "Q10.29_1", "Q12.29_1")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q29_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q29_value", "group")
survey_q29 <- rbind(survey_q29, temp_table)
}
survey_q29$q29_value <- as.numeric(survey_q29$q29_value)
Statistical test
# Initial Check
# summary(survey_q29$q29_value)
# check normality --> the data is not normally distributed
# shapiro.test(survey_q29$q29_value)
# run Kruskal-Wallis test
kruskal_test <- kruskal.test(q29_value ~ group, data = survey_q29)
print(kruskal_test)
Summary statistics
# Summary statistics
survey_q29_summary <- survey_q29 %>%
group_by(group) %>%
summarise(
mean = mean(q29_value, na.rm = TRUE),
median = median(q29_value, na.rm = TRUE),
sd = sd(q29_value, na.rm = TRUE)
)
Plot the distribution of different groups
# Grouped bar-style histogram
ggplot(survey_q29, aes(x = factor(q29_value), fill = factor(group))) +
geom_bar(position = "dodge") +
# facet_wrap(~ group) +
labs(
title = "Qxx.29 The distribution of representativeness of the uncertainty by group",
x = "Qxx.29 Response",
y = "Count",
fill = "Group"
) +
theme_minimal()
! Qxx.30 Readability of the Forecast
On a scale of 1 to 10, where 1 means very difficult and 10 means very
easy, how easy or difficult do you find the graph to understand?
1-Very difficult; 10-Very easy
Variable: continuous
Method: ANNOVA test or KW test (depends on whether it’s normally
distributed)
Result: Fail to reject the null hypothesis. There are
statistical difference between control group vs. fan chart slice group;
control group vs. bell curve; error bar group vs. bell curve
group.
# combine data from different groups
survey_q30 <- data.frame()
survey_q30_list <- list("Q4.30_1","Q6.30_1", "Q8.30_1", "Q10.30_1", "Q12.30_1")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q30_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q30_value", "group")
survey_q30 <- rbind(survey_q30, temp_table)
}
survey_q30$q30_value <- as.numeric(survey_q30$q30_value)
Statistical test
# Initial Check
# summary(survey_q30$q30_value)
# check normality --> the data is not normally distributed
# shapiro.test(survey_q30$q30_value)
# run Kruskal-Wallis test
kruskal_test <- kruskal.test(q30_value ~ group, data = survey_q30)
print(kruskal_test)
Kruskal-Wallis rank sum test
data: q30_value by group
Kruskal-Wallis chi-squared = 21.14, df = 4, p-value = 0.0002971
# Post-hoc test
dunnTest(q30_value ~ group, data = survey_q30, method = "bonferroni")
Warning: group was coerced to a factor.Dunn (1964) Kruskal-Wallis multiple comparison
p-values adjusted with the Bonferroni method.
Summary statistics
# Summary statistics
survey_q30_summary <- survey_q30 %>%
group_by(group) %>%
summarise(
mean = mean(q30_value, na.rm = TRUE),
median = median(q30_value, na.rm = TRUE),
sd = sd(q30_value, na.rm = TRUE)
)
Plot the distribution of different groups
# Grouped bar-style histogram
ggplot(survey_q30, aes(x = factor(q30_value), fill = factor(group))) +
geom_bar(position = "dodge") +
# facet_wrap(~ group) +
labs(
title = "Qxx.30 The distribution of readability of the forecast by group",
x = "Qxx.30 Response",
y = "Count",
fill = "Group"
) +
theme_minimal()

Qxx.31 Trust of the Forecast
On a scale of 1 to 10, where 1 means you don’t trust the inflation
forecast at all and 10 means you fully trust it, how much do you trust
the inflation forecast shown in the graph?
1-Don’t trust at all; 10-Fully trust
Variable: continuous
Method: ANNOVA test or KW test (depends on whether it’s normally
distributed)
Result: Fail to reject the null hypothesis.
# combine data from different groups
survey_q31 <- data.frame()
survey_q31_list <- list("Q4.31_1","Q6.31_1", "Q8.31_1", "Q10.31_1", "Q12.31_1")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_q31_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q31_value", "group")
survey_q31 <- rbind(survey_q31, temp_table)
}
survey_q31$q31_value <- as.numeric(survey_q31$q31_value)
Statistical test
kruskal_test <- kruskal.test(q31_value ~ group, data = survey_q31)
print(kruskal_test)
Kruskal-Wallis rank sum test
data: q31_value by group
Kruskal-Wallis chi-squared = 3.7739, df = 4, p-value = 0.4375
Summary statistics
# Summary statistics
survey_q31_summary <- survey_q31 %>%
group_by(group) %>%
summarise(
mean = mean(q31_value, na.rm = TRUE),
median = median(q31_value, na.rm = TRUE),
sd = sd(q31_value, na.rm = TRUE)
)
Plot the distribution of different groups
# Grouped bar-style histogram
ggplot(survey_q31, aes(x = factor(q31_value), fill = factor(group))) +
geom_bar(position = "dodge") +
# facet_wrap(~ group) +
labs(
title = "Qxx.31 The distribution of trust of the forecast by group",
x = "Qxx.31 Response",
y = "Count",
fill = "Group"
) +
theme_minimal()

Skewed Data
Qxx.33 Probability of higher than 3%
Based on the inflation forecast provided, what do you think is the
probability of inflation ending up higher than 3%?
Definitive Correct Answer - 5
Variable: categorical
Method: contingency table & proportion test
Result: There is no statistical difference across different
groups and the largest proportion of participants can understand the
probability correctly, but only account for 28% of the entire
respondents.
# combine data from different groups
survey_q33 <- data.frame()
survey_q33_list <- list("Q6.33","Q8.33", "Q10.33", "Q12.33")
for (i in seq_along(skewed_group_list)) {
df <- skewed_group_list[[i]]
col <- survey_q33_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q33_value", "group")
survey_q33 <- rbind(survey_q33, temp_table)
}
survey_q33$q33_value <- as.numeric(survey_q33$q33_value)
Test the proportion of correct answer
survey_q33_contingency <- table(survey_q33$q33_value, survey_q33$group)
print(survey_q33_contingency)
1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 14 12 11 7
2 8 12 10 16
3 9 10 20 11
4 4 5 6 5
5 24 22 19 22
survey_q33_correct <- survey_q33_contingency[5,]
survey_q33_group_total <- colSums(survey_q33_contingency)
prop.test(survey_q33_correct, survey_q33_group_total)
4-sample test for equality of proportions without continuity
correction
data: survey_q33_correct out of survey_q33_group_total
X-squared = 2.0053, df = 3, p-value = 0.5713
alternative hypothesis: two.sided
sample estimates:
prop 1 prop 2 prop 3 prop 4
0.4067797 0.3606557 0.2878788 0.3606557
Plot probability of higher than 3% (proportion bar plot across
different groups)
survey_q33_prop <- as.data.frame(survey_q33_contingency)
# rename columns
names(survey_q33_prop) <- c("Qxx.33", "Group", "Count")
# add a labelled column
survey_q33_prop <- survey_q33_prop %>%
mutate(Qxx.33_label = case_when(
Qxx.33 == "1" ~ "1-More than 60%",
Qxx.33 == "2" ~ "3-40-50%",
Qxx.33 == "3" ~ "4-30-40%",
Qxx.33 == "4" ~ "5-Less than 30%",
Qxx.33 == "5" ~ "2-50-60%"
))
# calculate proportions within each group
survey_q33_prop <- survey_q33_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_q33_prop, aes(x = as.factor(`Qxx.33_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
# facet_wrap(~Group)+
labs(
title = "Qxx.33 Answer Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot the histogram including all participants
# force order for graph
survey_q33 <- survey_q33 %>%
mutate(
q33_value_re = factor(
q33_value,
levels = c(1, 5, 2, 3, 4)
)
)
# histogram including all participants
ggplot(survey_q33, aes(x = q33_value_re)) +
geom_bar(fill = "steelblue", color = "white") +
labs(
title = "Qxx.33 Responses (forced 1-5-2-3-4 order)",
x = "Qxx.33",
y = "Count"
) +
theme_minimal()

Qxx.34 Self-reported likelihood of inflation being higher than
3%
How likely do you think it is that the inflation will be higher than
3%?
ascending value-increasing likelihood
Variable: treat as continuous
Method: Kruskal-Wallis test
Result: Fail to reject the null hypothesis. The majority of
respondents think it’s quite likely.
# combine data from different groups
survey_q34 <- data.frame()
survey_q34_list <- list("Q6.34_1","Q8.34_1", "Q10.34_1", "Q12.34_1")
for (i in seq_along(skewed_group_list)) {
df <- skewed_group_list[[i]]
col <- survey_q34_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q34_value", "group")
survey_q34 <- rbind(survey_q34, temp_table)
}
survey_q34$q34_value <- as.numeric(survey_q34$q34_value)
KW test
# check normality --> the data is not normally distributed
# shapiro.test(survey_q34$q34_value)
# run Kruskal-Wallis test
kruskal_test <- kruskal.test(q34_value ~ group, data = survey_q34)
print(kruskal_test)
Kruskal-Wallis rank sum test
data: q34_value by group
Kruskal-Wallis chi-squared = 5.5506, df = 3, p-value = 0.1356
Plot the distribution of different groups

Plot bar chart including all participants
# histogram including all participants
ggplot(survey_q34, aes(x = q34_value)) +
geom_histogram(binwidth = 1, fill = "steelblue", color = "white") +
# facet_wrap(~ group) +
labs(title = "Qxx.34 Self-reported likelihood of inflation being higher than 3% distribution",
x = "Qxx.34",
y = "Count") +
scale_x_continuous(breaks = as.numeric(names(likelihood_labels)),
labels = likelihood_labels) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Qxx.36 Deviation from central estimate
Based on the inflation forecast provided, do you think there is a
higher risk of inflation exceeding the central estimate or of being less
than this central estimate?
Definitive Correct Answer - 1
Variable: categorical
Method: contingency table & proportion test
Result: There is no statistical difference across group. 68% of
respondents can understand there is bigger upside risk.
# combine data from different groups
survey_q36 <- data.frame()
survey_q36_list <- list("Q6.36","Q8.36", "Q10.36", "Q12.36")
for (i in seq_along(skewed_group_list)) {
df <- skewed_group_list[[i]]
col <- survey_q36_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q36_value", "group")
survey_q36 <- rbind(survey_q36, temp_table)
}
survey_q36$q36_value <- as.numeric(survey_q36$q36_value)
Contingency table
survey_q36_contingency <- table(survey_q36$q36_value, survey_q36$group)
print(survey_q36_contingency)
1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 38 42 47 41
2 5 1 7 6
3 16 18 12 14
chisq_result <- chisq.test(survey_q36_contingency)
Warning: Chi-squared approximation may be incorrect
print(chisq_result)
Pearson's Chi-squared test
data: survey_q36_contingency
X-squared = 6.2063, df = 6, p-value = 0.4005
Test the proportion of correct answer
survey_q36_correct <- survey_q36_contingency[1,]
survey_q36_group_total <- colSums(survey_q36_contingency)
prop.test(survey_q36_correct, survey_q36_group_total)
4-sample test for equality of proportions without continuity
correction
data: survey_q36_correct out of survey_q36_group_total
X-squared = 0.70091, df = 3, p-value = 0.873
alternative hypothesis: two.sided
sample estimates:
prop 1 prop 2 prop 3 prop 4
0.6440678 0.6885246 0.7121212 0.6721311
Plot proportion bar plot across different groups
survey_q36_prop <- as.data.frame(survey_q36_contingency)
# rename columns
names(survey_q36_prop) <- c("Qxx.36", "Group", "Count")
# add a labelled column
survey_q36_prop <- survey_q36_prop %>%
mutate(Qxx.36_label = case_when(
Qxx.36 == "1" ~ "1-bigger upside risk",
Qxx.36 == "2" ~ "2-bigger downside risk",
Qxx.36 == "3" ~ "3-equal risks on both sides"
))
# calculate proportions within each group
survey_q36_prop <- survey_q36_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_q36_prop, aes(x = as.factor(`Qxx.36_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
# facet_wrap(~Group)+
labs(
title = "Qxx.36 Answer Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot the histogram including all participants
# histogram including all participants
ggplot(survey_q36, aes(x = q36_value)) +
geom_histogram(binwidth = 1, fill = "steelblue", color = "white") +
# facet_wrap(~ group) +
labs(title = "Qxx.36 Answer Bar Chart",
x = "Qxx.36",
y = "Count") +
scale_x_continuous(breaks = seq(0, max(survey_q36$q36_value, na.rm = TRUE), by = 1)) +
theme_minimal()

? Qxx.37 Risk of ending outside
If the actual inflation ends up outside the black line, which side is
more likely, based on the uncertainty depicted in the graph?
Definitive Correct Answer - 1
Variable: categorical
Method: contingency table & proportion test
Result: 63% respondents think if the actual inflation ends up
outside, it’s more likely to be on the upper side.
# combine data from different groups
survey_q37 <- data.frame()
survey_q37_list <- list("Q6.37","Q8.37", "Q10.37", "Q12.37")
for (i in seq_along(skewed_group_list)) {
df <- skewed_group_list[[i]]
col <- survey_q37_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("q37_value", "group")
survey_q37 <- rbind(survey_q37, temp_table)
}
survey_q37$q37_value <- as.numeric(survey_q37$q37_value)
Contingency table
# pairwise proportion test
pairwise.prop.test(
x = survey_q37_contingency[1,],
n = colSums(survey_q37_contingency),
p.adjust.method = "bonferroni" # or "holm", "BH"
)
Pairwise comparisons using Pairwise comparison of proportions
data: survey_q37_contingency[1, ] out of colSums(survey_q37_contingency)
1-errorbar 2-shadedbar 3-fanchartslice
2-shadedbar 1.00 - -
3-fanchartslice 0.11 0.16 -
4-bellcurve 1.00 1.00 0.40
P value adjustment method: bonferroni
Plot proportion bar plot across different groups
survey_q37_prop <- as.data.frame(survey_q37_contingency)
# rename columns
names(survey_q37_prop) <- c("Qxx.37", "Group", "Count")
# add a labelled column
survey_q37_prop <- survey_q37_prop %>%
mutate(Qxx.37_label = case_when(
Qxx.37 == "1" ~ "1-More likely to be on the upper side",
Qxx.37 == "2" ~ "2-More likely to be on the lower side",
Qxx.37 == "3" ~ "3-Equal chances of being on either side"
))
# calculate proportions within each group
survey_q37_prop <- survey_q37_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_q37_prop, aes(x = as.factor(`Qxx.37_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
# facet_wrap(~Group)+
labs(
title = "Qxx.37 Answer Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot the histogram including all participants
# histogram including all participants
ggplot(survey_q37, aes(x = q37_value)) +
geom_histogram(binwidth = 1, fill = "steelblue", color = "white") +
# facet_wrap(~ group) +
labs(title = "Qxx.37 Answer Bar Chart",
x = "Qxx.37",
y = "Count") +
scale_x_continuous(breaks = seq(0, max(survey_q37$q37_value, na.rm = TRUE), by = 1)) +
theme_minimal()

Decision-making
D.3 Investment Decision
Which bond would you choose to invest in?
Variable: categorical
Method: contingency table & proportion test
Result: Fail to reject the null hypothesis.
# combine data from different groups
survey_d3 <- data.frame()
survey_d3_list <- list("Q5.3","Q7.3", "Q9.3", "Q11.3", "Q13.3")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_d3_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("d3_value", "group")
survey_d3 <- rbind(survey_d3, temp_table)
}
survey_d3$d3_value <- as.numeric(survey_d3$d3_value)
Contingency table
survey_d3_contingency <- table(survey_d3$d3_value, survey_d3$group)
print(survey_d3_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 22 17 24 22 17
2 40 42 37 44 44
# chi-squared test
chisq.test(survey_d3_contingency)
Pearson's Chi-squared test
data: survey_d3_contingency
X-squared = 2.4805, df = 4, p-value = 0.6481
Plot proportion bar plot across different groups
survey_d3_prop <- as.data.frame(survey_d3_contingency)
# rename columns
names(survey_d3_prop) <- c("D.3", "Group", "Count")
# add a labelled column
survey_d3_prop <- survey_d3_prop %>%
mutate(D.3_label = case_when(
D.3 == "1" ~ "A. Nominal Bond",
D.3 == "2" ~ "B. Inflation-Protected Bond"
))
# calculate proportions within each group
survey_d3_prop <- survey_d3_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_d3_prop, aes(x = as.factor(`D.3_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
# facet_wrap(~Group)+
labs(
title = "D.3 Answer Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot pie chart including all participants
survey_d3_summary <- survey_d3_prop %>%
group_by(`D.3_label`) %>%
summarise(total_count = sum(Count), .groups = "drop") %>%
mutate(proportion = total_count / sum(total_count),
`D.3_graph_label` = paste0(`D.3_label`, " (", round(proportion * 100, 2), " %)"))
ggplot(survey_d3_summary, aes(x = "",y = proportion, fill = `D.3_graph_label`)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
labs(title = "D.3 Investment Decision Summary Pie Chart",
x = "",
y = "") +
theme_minimal() +
theme(axis.text.x = element_blank())

D.4 Confidence in decision-making
On a scale of 1 to 10, where 1 means not confident at all and 10
means very confident, how confident are you in making the
decision?
1-Not confident at all; 10-Very confident
Variable: continuous
Method: ANNOVA test or KW test (depends on whether it’s normally
distributed)
Result: Fail to reject the null hypothesis.
# combine data from different groups
survey_d4 <- data.frame()
survey_d4_list <- list("Q5.4_1","Q7.4_1", "Q9.4_1", "Q11.4_1", "Q13.4_1")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_d4_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("d4_value", "group")
survey_d4 <- rbind(survey_d4, temp_table)
}
survey_d4$d4_value <- as.numeric(survey_d4$d4_value)
Statistical test
# Initial Check
# summary(survey_d4$d4_value)
# check normality --> the data is not normally distributed
# shapiro.test(survey_d4$d4_value)
# run Kruskal-Wallis test
kruskal_test <- kruskal.test(d4_value ~ group, data = survey_d4)
print(kruskal_test)
Kruskal-Wallis rank sum test
data: d4_value by group
Kruskal-Wallis chi-squared = 7.0487, df = 4, p-value = 0.1333
Summary statistics
# Summary statistics
survey_d4_summary <- survey_d4 %>%
group_by(group) %>%
summarise(
mean = mean(d4_value, na.rm = TRUE),
median = median(d4_value, na.rm = TRUE),
sd = sd(d4_value, na.rm = TRUE)
)
Plot the distribution of different groups
# Grouped bar-style histogram
ggplot(survey_d4, aes(x = factor(d4_value), fill = factor(group))) +
geom_bar(position = "dodge") +
facet_wrap(~ group) +
labs(
title = "D.4 The distribution of confidence in decision-making by group",
x = "D.4 Response",
y = "Count",
fill = "Group"
) +
theme_minimal()

D.6 Considering nominal bond
If the probability of inflation being low (≤ 3%) is greater than the
following percentages, I would consider investing in the nominal
bond:
Variable: categorical
Method: contingency table & chi-squared test
Result: Fail to reject the null hypothesis.
# combine data from different groups
survey_d6 <- data.frame()
survey_d6_list <- list("Q5.6","Q7.6", "Q9.6", "Q11.6", "Q13.6")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_d6_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("d6_value", "group")
survey_d6 <- rbind(survey_d6, temp_table)
}
survey_d6$d6_value <- as.numeric(survey_d6$d6_value)
Contingency table
survey_d6_contingency <- table(survey_d6$d6_value, survey_d6$group)
print(survey_d6_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 0 1 0 3 2
2 2 4 1 4 3
3 6 5 8 2 2
4 2 5 5 6 9
5 15 10 8 12 10
7 6 8 7 14 8
8 9 9 8 3 10
# run chi-squared test
chisq_result <- chisq.test(survey_d6_contingency)
Warning: Chi-squared approximation may be incorrect
print(chisq_result)
Pearson's Chi-squared test
data: survey_d6_contingency
X-squared = 28.8, df = 24, p-value = 0.2277
Plot proportion bar plot across different groups
survey_d6_prop <- as.data.frame(survey_d6_contingency)
# rename columns
names(survey_d6_prop) <- c("D.6", "Group", "Count")
# add a labelled column
survey_d6_prop <- survey_d6_prop %>%
mutate(D.6_label = case_when(
D.6 == "1" ~ "1-40%",
D.6 == "2" ~ "2-50%",
D.6 == "3" ~ "3-60%",
D.6 == "4" ~ "4-do not think about probability",
D.6 == "5" ~ "5-choose an inflation-protected bond",
D.6 == "7" ~ "6-70%",
D.6 == "8" ~ "7-80%"
))
# calculate proportions within each group
survey_d6_prop <- survey_d6_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_d6_prop, aes(x = as.factor(`D.6_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
# facet_wrap(~Group)+
labs(
title = "D.6 Answer Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot the histogram including all participants
# histogram including all participants
ggplot(survey_d6, aes(x = d6_value)) +
geom_histogram(binwidth = 1, fill = "steelblue", color = "white") +
# facet_wrap(~ group) +
labs(title = "D.6 Histogram",
x = "D.6",
y = "Count") +
scale_x_continuous(breaks = seq(0, max(survey_d6$d6_value, na.rm = TRUE), by = 1)) +
theme_minimal()

D.7 Considering inflation-protected bond
If the probability of inflation being high (> 3%) is greater than
the following percentages, I would consider investing in the
inflation-protected bond:
Variable: categorical
Method: contingency table & chi-squared test
*Result: Fail to reject the null hypothesis.**
# combine data from different groups
survey_d7 <- data.frame()
survey_d7_list <- list("Q5.7","Q7.7", "Q9.7", "Q11.7", "Q13.7")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_d7_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("d7_value", "group")
survey_d7 <- rbind(survey_d7, temp_table)
}
survey_d7$d7_value <- as.numeric(survey_d7$d7_value)
Contingency table
survey_d7_contingency <- table(survey_d7$d7_value, survey_d7$group)
print(survey_d7_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 2 0 5 1 0
2 3 4 0 6 3
3 2 4 6 5 5
4 6 1 4 3 4
5 1 3 1 4 3
7 3 4 7 2 2
8 5 1 1 1 0
# run chi-squared test
chisq_result <- chisq.test(survey_d7_contingency)
Warning: Chi-squared approximation may be incorrect
print(chisq_result)
Pearson's Chi-squared test
data: survey_d7_contingency
X-squared = 35.733, df = 24, p-value = 0.05824
Plot proportion bar plot across different groups
survey_d7_prop <- as.data.frame(survey_d7_contingency)
# rename columns
names(survey_d7_prop) <- c("D.7", "Group", "Count")
# add a labelled column
survey_d7_prop <- survey_d7_prop %>%
mutate(D.7_label = case_when(
D.7 == "1" ~ "1-40%",
D.7 == "2" ~ "2-50%",
D.7 == "3" ~ "3-60%",
D.7 == "4" ~ "4-do not think about probability",
D.7 == "5" ~ "5-always choose a nominal bond",
D.7 == "7" ~ "6-70%",
D.7 == "8" ~ "7-80%"
))
# calculate proportions within each group
survey_d7_prop <- survey_d7_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_d7_prop, aes(x = as.factor(`D.7_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
facet_wrap(~Group)+
labs(
title = "D.7 Answer Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot the histogram including all participants
# histogram including all participants
ggplot(survey_d7, aes(x = d7_value)) +
geom_histogram(binwidth = 1, fill = "steelblue", color = "white") +
# facet_wrap(~ group) +
labs(title = "D.7 Histogram",
x = "D.7",
y = "Count") +
scale_x_continuous(breaks = seq(0, max(survey_d7$d7_value, na.rm = TRUE), by = 1)) +
theme_minimal()

D.8 Impact on Desicion-making
Considering the payoff for the Nominal Bond, which of the following
has a larger impact on your decision-making?
Variable: categorical
Method: contingency table & chi-squared test
Result: Fail to reject the null hypothesis.
# combine data from different groups
survey_d8 <- data.frame()
survey_d8_list <- list("Q5.8","Q7.8", "Q9.8", "Q11.8", "Q13.8")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_d8_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("d8_value", "group")
survey_d8 <- rbind(survey_d8, temp_table)
}
survey_d8$d8_value <- as.numeric(survey_d8$d8_value)
Contingency table
survey_d8_contingency <- table(survey_d8$d8_value, survey_d8$group)
print(survey_d8_contingency)
0-controlled 1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 33 28 35 43 40
2 16 15 19 12 13
3 13 16 7 11 8
# run chi-squared test
chisq_result <- chisq.test(survey_d8_contingency)
print(chisq_result)
Pearson's Chi-squared test
data: survey_d8_contingency
X-squared = 10.474, df = 8, p-value = 0.2333
Plot proportion bar plot across different groups
survey_d8_prop <- as.data.frame(survey_d8_contingency)
# rename columns
names(survey_d8_prop) <- c("D.8", "Group", "Count")
# add a labelled column
survey_d8_prop <- survey_d8_prop %>%
mutate(D.8_label = case_when(
D.8 == "1" ~ "1-potential loss",
D.8 == "2" ~ "2-potential gain",
D.8 == "3" ~ "3-potential loss and gain have the same impact"
))
# calculate proportions within each group
survey_d8_prop <- survey_d8_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_d8_prop, aes(x = as.factor(`D.8_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
# facet_wrap(~Group)+
labs(
title = "D.8 Answer Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot the histogram including all participants
# histogram including all participants
ggplot(survey_d8, aes(x = d8_value)) +
geom_histogram(binwidth = 1, fill = "steelblue", color = "white") +
# facet_wrap(~ group) +
labs(title = "D.8 Histogram",
x = "D.8",
y = "Count") +
scale_x_continuous(breaks = seq(0, max(survey_d8$d8_value, na.rm = TRUE), by = 1)) +
theme_minimal()

D.9 Effectiveness of the graph for decision-making
On a scale of 1 to 10, where 1 means the forecast was not effective
at all and 10 means it was very effective, how effective do you think
the forecast was in assisting your decision-making?
1-Not effective at all; 10-Very effective
Variable: continuous
Method: ANNOVA test or KW test (depends on whether it’s normally
distributed)
Result: At least one group is statistically significant than
others.
# combine data from different groups
survey_d9 <- data.frame()
survey_d9_list <- list("Q5.9_1","Q7.9_1", "Q9.9_1", "Q11.9_1", "Q13.9_1")
for (i in seq_along(group_list)) {
df <- group_list[[i]]
col <- survey_d9_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("d9_value", "group")
survey_d9 <- rbind(survey_d9, temp_table)
}
survey_d9$d9_value <- as.numeric(survey_d9$d9_value)
Statistical test
# Initial Check
# summary(survey_d9$d9_value)
# check normality --> the data is not normally distributed
# shapiro.test(survey_d9$d9_value)
# run Kruskal-Wallis test
kruskal_test <- kruskal.test(d9_value ~ group, data = survey_d9)
print(kruskal_test)
Kruskal-Wallis rank sum test
data: d9_value by group
Kruskal-Wallis chi-squared = 10.047, df = 4, p-value = 0.03964
# Post-hoc test
dunnTest(d9_value ~ group, data = survey_d9, method = "bonferroni")
Warning: group was coerced to a factor.Dunn (1964) Kruskal-Wallis multiple comparison
p-values adjusted with the Bonferroni method.
Summary statistics
# Summary statistics
survey_d9_summary <- survey_d9 %>%
group_by(group) %>%
summarise(
mean = mean(d9_value, na.rm = TRUE),
median = median(d9_value, na.rm = TRUE),
sd = sd(d9_value, na.rm = TRUE)
)
Plot the distribution of different groups
# Grouped bar-style histogram
ggplot(survey_d9, aes(x = factor(d9_value), fill = factor(group))) +
geom_bar(position = "dodge") +
# facet_wrap(~ group) +
labs(
title = "D.9 The distribution of effectiveness of the graph for decision-making by group",
x = "D.9 Response",
y = "Count",
fill = "Group"
) +
theme_minimal()

? D.12 Skewed Investment Decision
Which bond would you choose to invest in?
Variable: categorical
Method: contingency table & chi-squared test
Result: There is significant difference in at least one
group.
# combine data from different groups
survey_d12 <- data.frame()
survey_d12_list <- list("Q7.12", "Q9.12", "Q11.12", "Q13.12")
for (i in seq_along(skewed_group_list)) {
df <- skewed_group_list[[i]]
col <- survey_d12_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("d12_value", "group")
survey_d12 <- rbind(survey_d12, temp_table)
}
survey_d12$d12_value <- as.numeric(survey_d12$d12_value)
Contingency table
print(survey_d12_contingency)
1-errorbar 2-shadedbar 3-fanchartslice 4-bellcurve
1 8 21 25 8
2 51 40 41 53
Plot proportion bar plot across different groups
survey_d12_prop <- as.data.frame(survey_d12_contingency)
# rename columns
names(survey_d12_prop) <- c("D.12", "Group", "Count")
# add a labelled column
survey_d12_prop <- survey_d12_prop %>%
mutate(D.12_label = case_when(
D.12 == "1" ~ "A. Nominal Bond",
D.12 == "2" ~ "B. Inflation-Protected Bond"
))
# calculate proportions within each group
survey_d12_prop <- survey_d12_prop %>%
group_by(Group) %>%
mutate(Proportion = Count / sum(Count))
ggplot(survey_d12_prop, aes(x = as.factor(`D.12_label`), y = Proportion, fill = Group)) + geom_col(position = "dodge") +
# facet_wrap(~Group)+
labs(
title = "D.12 Answer Propotion Plot across Groups",
x = "Response",
y = "Proportion"
) +
scale_fill_brewer(palette = "Set2")+
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Plot pie chart including all participants
survey_d12_summary <- survey_d12_prop %>%
group_by(`D.12_label`) %>%
summarise(total_count = sum(Count), .groups = "drop") %>%
mutate(proportion = total_count / sum(total_count),
`D.12_graph_label` = paste0(`D.12_label`, " (", round(proportion * 100, 2), " %)"))
ggplot(survey_d12_summary, aes(x = "",y = proportion, fill = `D.12_graph_label`)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
labs(title = "D.12 Investment Decision Summary Pie Chart",
x = "",
y = "") +
theme_minimal() +
theme(axis.text.x = element_blank())

D.13 Skewed Confidentce in decision-making
On a scale of 1 to 10, where 1 means not confident at all and 10
means very confident, how confident are you in making the
decision?
1-Not confident at all; 10-Very confident
Variable: continuous
Method: ANNOVA test or KW test (depends on whether it’s normally
distributed)
Result: At least one group is statistically significant than
others.
# combine data from different groups
survey_d13 <- data.frame()
survey_d13_list <- list("Q7.13_1", "Q9.13_1", "Q11.13_1", "Q13.13_1")
for (i in seq_along(skewed_group_list)) {
df <- skewed_group_list[[i]]
col <- survey_d13_list[[i]]
temp_table <- df[, c(col, "group")]
names(temp_table) <- c("d13_value", "group")
survey_d13 <- rbind(survey_d13, temp_table)
}
survey_d13$d13_value <- as.numeric(survey_d13$d13_value)
Statistical test
anova_test <- aov(d13_value ~ group, data = survey_d13)
summary(anova_test)
Df Sum Sq Mean Sq F value Pr(>F)
group 3 14.2 4.721 1.181 0.317
Residuals 243 971.1 3.996
Summary statistics
# Summary statistics
survey_d13_summary <- survey_d13 %>%
group_by(group) %>%
summarise(
mean = mean(d13_value, na.rm = TRUE),
median = median(d13_value, na.rm = TRUE),
sd = sd(d13_value, na.rm = TRUE)
)
Plot the distribution of different groups
# Grouped bar-style histogram
ggplot(survey_d13, aes(x = factor(d13_value), fill = factor(group))) +
geom_bar(position = "dodge") +
# facet_wrap(~ group) +
labs(
title = "D.13 The distribution of confidence in decision-making by group",
x = "D.13 Response",
y = "Count",
fill = "Group"
) +
theme_minimal()

LS0tDQp0aXRsZTogIk5vcmEgTWFzdGVyIFByb2plY3QgRGF0YSBBbmFseXNpcyBOb3RlYm9vayINCmF1dGhvcjogIk5vcmEgTHVvIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCiMgVGFibGUgb2YgQ29udGVudHMNCjEuIFtOb3RhdGlvbl0oI25vdGF0aW9uKQ0KMi4gW0xvYWQgYW5kIHNwbGl0IHRoZSBkYXRhXSgjbG9hZC1hbmQtc3BsaXQtdGhlLWRhdGEpDQozLiBbU2NyZWVuaW5nIFF1ZXN0aW9uc10oI3NjcmVlbmluZy1xdWVzdGlvbnMpDQo0LiBbQWN0dWFsIFN1cnZleSBBbmFseXNpc10oI2FjdHVhbC1zdXJ2ZXktYW5hbHlzaXMpDQo1LiBbU3RhdGlzdGljYWwgVGVzdGluZ10oI3N0YXRpc3RpY2FsLXRlc3RpbmcpDQo2LiBbU2tld2VkIERhdGFdKCNza2V3ZWQtZGF0YSkNCjcuIFtEZWNpc2lvbi1tYWtpbmddKCNkZWNpc2lvbi1tYWtpbmcpDQoNCg0KVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4NCg0KVHJ5IGV4ZWN1dGluZyB0aGlzIGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuayBvciBieSBwbGFjaW5nIHlvdXIgY3Vyc29yIGluc2lkZSBpdCBhbmQgcHJlc3NpbmcgKkN0cmwrU2hpZnQrRW50ZXIqLg0KDQpgYGB7cn0NCnBsb3QoY2FycykNCmBgYA0KDQpBZGQgYSBuZXcgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpJbnNlcnQgQ2h1bmsqIGJ1dHRvbiBvbiB0aGUgdG9vbGJhciBvciBieSBwcmVzc2luZyAqQ3RybCtBbHQrSSouDQoNCldoZW4geW91IHNhdmUgdGhlIG5vdGVib29rLCBhbiBIVE1MIGZpbGUgY29udGFpbmluZyB0aGUgY29kZSBhbmQgb3V0cHV0IHdpbGwgYmUgc2F2ZWQgYWxvbmdzaWRlIGl0IChjbGljayB0aGUgKlByZXZpZXcqIGJ1dHRvbiBvciBwcmVzcyAqQ3RybCtTaGlmdCtLKiB0byBwcmV2aWV3IHRoZSBIVE1MIGZpbGUpLg0KDQpUaGUgcHJldmlldyBzaG93cyB5b3UgYSByZW5kZXJlZCBIVE1MIGNvcHkgb2YgdGhlIGNvbnRlbnRzIG9mIHRoZSBlZGl0b3IuIENvbnNlcXVlbnRseSwgdW5saWtlICpLbml0KiwgKlByZXZpZXcqIGRvZXMgbm90IHJ1biBhbnkgUiBjb2RlIGNodW5rcy4gSW5zdGVhZCwgdGhlIG91dHB1dCBvZiB0aGUgY2h1bmsgd2hlbiBpdCB3YXMgbGFzdCBydW4gaW4gdGhlIGVkaXRvciBpcyBkaXNwbGF5ZWQuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBSRUFETUUNCi0gcnVuIHRoZSBMb2FkIGFuZCBzcGxpdCB0aGUgZGF0YSBjaHVuayBmaXJzdA0KLSByZXN1bHRzIHdhcyBmaWx0ZXJlZCBiYXNlZCBvbiBRMy45IC0gd2hldGhlciByZXNwb25kZW50cyB1bmRlcnN0YW5kIHRoZSBjb25jZXB0IG9mIGluZmxhdGlvbiANCi0gISA6IFdlIGNhbiByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcy5cDQoNCg0KIyBMb2FkIGFuZCBzcGxpdCB0aGUgZGF0YSA8YSBuYW1lPSJsb2FkLWFuZC1zcGxpdC10aGUtZGF0YSI+PC9hPg0KDQpgYGB7cn0NCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkoRlNBKQ0KbGlicmFyeShjYXIpDQoNCg0KDQpleHBvcnRlZF9kYXRhIDwtIHJlYWRfY3N2KCJmaW5hbF9yYXdkYXRhX3ZhbHVlXzE2MDUuY3N2IikNCmV4cG9ydGVkX2RhdGEgPC0gc3Vic2V0KGV4cG9ydGVkX2RhdGEsIHNlbGVjdCA9IC1jKFN0YXJ0RGF0ZSxFbmREYXRlLFN0YXR1cyxJUEFkZHJlc3MsUHJvZ3Jlc3MsRmluaXNoZWQsUmVjb3JkZWREYXRlLCBSZWNpcGllbnRMYXN0TmFtZSxSZWNpcGllbnRGaXJzdE5hbWUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlY2lwaWVudEVtYWlsLEV4dGVybmFsUmVmZXJlbmNlLExvY2F0aW9uTGF0aXR1ZGUsTG9jYXRpb25Mb25naXR1ZGUsRGlzdHJpYnV0aW9uQ2hhbm5lbCxVc2VyTGFuZ3VhZ2UpKQ0KcmF3ZGF0YV92YWx1ZSA8LSBzdWJzZXQoZXhwb3J0ZWRfZGF0YSwgc2VsZWN0ID0tYyhSZXNwb25zZUlkLFExLjEsUTIuMSkpDQpyYXdkYXRhX3ZhbHVlIDwtIHJhd2RhdGFfdmFsdWVbMzpucm93KHJhd2RhdGFfdmFsdWUpLCBdDQoNCiMgbGFiZWwgdGhlIGdyb3VwDQpyYXdkYXRhX3ZhbHVlIDwtIHJhd2RhdGFfdmFsdWUgJT4lDQogIG11dGF0ZShncm91cCA9IGNhc2Vfd2hlbigNCiAgICAhaXMubmEoUTQuMikgIH4gJzAtY29udHJvbGxlZCcsDQogICAgIWlzLm5hKFE2LjIpICB+ICcxLWVycm9yYmFyJywNCiAgICAhaXMubmEoUTguMikgIH4gJzItc2hhZGVkYmFyJywNCiAgICAhaXMubmEoUTEwLjIpIH4gJzMtZmFuY2hhcnRzbGljZScsDQogICAgIWlzLm5hKFExMi4yKSB+ICc0LWJlbGxjdXJ2ZScNCiAgKSkNCiMgY3JlYXRlIGEgY29weSBvZiB0aGUgZGF0YSBmb3IgUTMuOSBhbmFseXNpcw0KcmF3ZGF0YV9xM185IDwtIHJhd2RhdGFfdmFsdWUNCiMgZmlsdGVyIHBhcnRpY2lwYW50cyB3aG8gZG8gbm90IHVuZGVyc3RhbmQgdGhlIGNvbmNlcHQgb2YgaW5mbGF0aW9uDQpyYXdkYXRhX3ZhbHVlIDwtIHJhd2RhdGFfdmFsdWVbcmF3ZGF0YV92YWx1ZSRRMy45ID09ICI0IiwgXQ0KDQojIHJhd2RhdGFfdmFsdWUgPC0gcmF3ZGF0YV92YWx1ZSAlPiUNCiMgICBtdXRhdGUoZ3JvdXAgPSBjYXNlX3doZW4oDQojICAgICAhaXMubmEoUTQuMikgIH4gMCwNCiMgICAgICFpcy5uYShRNi4yKSAgfiAxLA0KIyAgICAgIWlzLm5hKFE4LjIpICB+IDIsDQojICAgICAhaXMubmEoUTEwLjIpIH4gMywNCiMgICAgICFpcy5uYShRMTIuMikgfiA0DQojICAgKSkNCg0KIyBtZXRhLWRhdGENCnRvdGFsX3Jlc3BvbmRlbnRzIDwtIG5yb3cocmF3ZGF0YV92YWx1ZSkNCg0KDQpncm91cF90b3RhbCA8LSByYXdkYXRhX3ZhbHVlICU+JQ0KICBncm91cF9ieShncm91cCkgJT4lDQogIHN1bW1hcmlzZShuX3Jlc3BvbmRlbnRzID0gbigpKQ0KDQp0b3RhbF90cmVhdG1lbnRfcmVzcG9kZW50cyA8LSB0b3RhbF9yZXNwb25kZW50cyAtIGdyb3VwX3RvdGFsJG5fcmVzcG9uZGVudHNbMV0NCiAgDQogIA0KIyBncmFwaCBwcmVwYXJhdGlvbg0KDQpsaWtlbGlob29kX2xhYmVscyA9IGMoDQogICAgIjkiID0gIkV4Y2VwdGlvbmFsbHkgdW5saWtlbHkiLA0KICAgICIxMCIgPSAiVmVyeSB1bmxpa2VseSIsDQogICAgIjExIiA9ICJRdWl0ZSB1bmxpa2VseSIsDQogICAgIjEyIiA9ICJGaWZ0eS1maWZ0eSIsDQogICAgIjEzIiA9ICJRdWl0ZSBsaWtlbHkiLA0KICAgICIxNCIgPSAiVmVyeSBsaWtlbHkiLA0KICAgICIxNSIgPSAiVmlydHVhbGx5IGNlcnRhaW4iDQogICkNCg0KIyBmaWx0ZXIgdHJlYXRtZW50IGdyb3Vwcw0KY29udHJvbGxlZF9ncm91cCA8LSByYXdkYXRhX3ZhbHVlWyFpcy5uYShyYXdkYXRhX3ZhbHVlJFE0LjIpLCBdDQplcnJvcl9iYXIgPC1yYXdkYXRhX3ZhbHVlWyFpcy5uYShyYXdkYXRhX3ZhbHVlJFE2LjIpLCBdDQpzaGFkZWRfYmFyIDwtcmF3ZGF0YV92YWx1ZVshaXMubmEocmF3ZGF0YV92YWx1ZSRROC4yKSwgXQ0KZmFuY2hhcnRfc2xpY2UgPC1yYXdkYXRhX3ZhbHVlWyFpcy5uYShyYXdkYXRhX3ZhbHVlJFExMC4yKSwgXQ0KYmVsbF9jdXJ2ZSA8LXJhd2RhdGFfdmFsdWVbIWlzLm5hKHJhd2RhdGFfdmFsdWUkUTEyLjIpLCBdDQoNCiMgYWRkaW5nIGxhYmVscyB0byB0aGUgZ3JvdXBzDQojIGNvbnRyb2xsZWRfZ3JvdXAkZ3JvdXAgPC0gMQ0KIyBlcnJvcl9iYXIkZ3JvdXAgPC0gMg0KIyBzaGFkZWRfYmFyJGdyb3VwIDwtIDMNCiMgZmFuY2hhcnRfc2xpY2UkZ3JvdXAgPC0gNA0KIyBiZWxsX2N1cnZlJGdyb3VwIDwtIDUNCg0KDQojIHJlbW92ZSB1bm5lY2Vzc2FyeSBjb2x1bW5zDQpjb250cm9sbGVkX2dyb3VwID0gY29udHJvbGxlZF9ncm91cFssZ3JlcGwoIl4oUTN8UTR8UTUpIixuYW1lcyhjb250cm9sbGVkX2dyb3VwKSl8bmFtZXMoY29udHJvbGxlZF9ncm91cCkgJWluJSBjKCJEdXJhdGlvbiAoaW4gc2Vjb25kcykiLCAiZ3JvdXAiKV0NCmVycm9yX2JhciA9IGVycm9yX2JhclssZ3JlcGwoIl4oUTN8UTZ8UTcpIixuYW1lcyhlcnJvcl9iYXIpKXwgbmFtZXMoZXJyb3JfYmFyKSAlaW4lIGMoIkR1cmF0aW9uIChpbiBzZWNvbmRzKSIsICJncm91cCIpXQ0Kc2hhZGVkX2JhciA9IHNoYWRlZF9iYXJbLGdyZXBsKCJeKFEzfFE4fFE5KSIsbmFtZXMoc2hhZGVkX2JhcikpfCBuYW1lcyhzaGFkZWRfYmFyKSVpbiUgYygiRHVyYXRpb24gKGluIHNlY29uZHMpIiwgImdyb3VwIildDQpmYW5jaGFydF9zbGljZSA9IGZhbmNoYXJ0X3NsaWNlWyxncmVwbCgiXihRM3xRMTB8UTExKSIsbmFtZXMoZmFuY2hhcnRfc2xpY2UpKXwgbmFtZXMoZmFuY2hhcnRfc2xpY2UpICVpbiUgYygiRHVyYXRpb24gKGluIHNlY29uZHMpIiwgImdyb3VwIildDQpiZWxsX2N1cnZlID0gYmVsbF9jdXJ2ZVssZ3JlcGwoIl4oUTN8UTEyfFExMykiLG5hbWVzKGJlbGxfY3VydmUpKXwgbmFtZXMoYmVsbF9jdXJ2ZSkgJWluJSBjKCJEdXJhdGlvbiAoaW4gc2Vjb25kcykiLCAiZ3JvdXAiKV0NCiMgY29udHJvbGxlZF9ncm91cCA9IGNvbnRyb2xsZWRfZ3JvdXBbLCFzYXBwbHkoY29udHJvbGxlZF9ncm91cCwgZnVuY3Rpb24oeCkgbWVhbihpcy5uYSh4KSkpPjAuOV0NCg0KZ3JvdXBfbGlzdCA8LSBsaXN0KA0KICBjb250cm9sbGVkID0gY29udHJvbGxlZF9ncm91cCwNCiAgZXJyb3JiYXIgPSBlcnJvcl9iYXIsDQogIHNoYWRlZGJhciA9IHNoYWRlZF9iYXIsDQogIGZhbmNoYXJ0c2xpY2UgPSBmYW5jaGFydF9zbGljZSwNCiAgYmVsbGN1cnZlID0gYmVsbF9jdXJ2ZQ0KKQ0KDQpza2V3ZWRfZ3JvdXBfbGlzdCA8LSBncm91cF9saXN0Wy0xXQ0KDQpgYGANCg0KIA0KIyBTY3JlZW5pbmcgUXVlc3Rpb25zIDxhIG5hbWU9InNjcmVlbmluZy1xdWVzdGlvbnMiPjwvYT4NCg0KIyMgISBUaW1lIER1cmF0aW9uDQpWYXJpYWJsZTogY29udGludW91cyA8YnI+IA0KTWV0aG9kOiBjaGVjayBub3JtYWxpdHkgKyBrcnVza2FsLXdhbGxpcyB0ZXN0ICsgcG9zdC1ob2MgdGVzdFwNCioqUmVzdWx0OiBwXDwgMC4wNS0tXD4gd2UgY2FuIHJlamVjdCB0aGUgaHlwb3RoZXNpcyoqIDxicj4gY29udHJvbGxlZCBncm91cCBpcyBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBmcm9tIChlcnJvciBiYXI7IHNoYWRlZCBiYXI7IGZhbmNoYXJ0IHNsaWNlOyBCVVQgTk9UIGZhbmNoYXJ0c2xpY2UpDQpgYGB7cn0NCnRpbWVfZHVyYXRpb25fdGFibGUgPC0gcmF3ZGF0YV92YWx1ZVssYygiRHVyYXRpb24gKGluIHNlY29uZHMpIiwgImdyb3VwIildDQp0aW1lX2R1cmF0aW9uX3RhYmxlJGBEdXJhdGlvbiAoaW4gbWlucylgIDwtIGFzLm51bWVyaWModGltZV9kdXJhdGlvbl90YWJsZSRgRHVyYXRpb24gKGluIHNlY29uZHMpYCkvNjANCg0KIyByZXBvcnQgcXVhbnRpbGUgaW5mb3JtYXRpb24NCnN1bW1hcnkodGltZV9kdXJhdGlvbl90YWJsZSRgRHVyYXRpb24gKGluIG1pbnMpYCkNCg0KDQojIHRlc3QgZm9yIG5vcm1hbGl0eSAtLT4gSXQncyBkZWZpbml0ZWx5IG5vdCBub3JtYWwgZGlzdHJpYnV0aW9uDQojIHNoYXBpcm8udGVzdCh0aW1lX2R1cmF0aW9uX3RhYmxlJGBEdXJhdGlvbiAoaW4gbWlucylgKQ0KDQojIHJ1biB0aGUga3J1c2thbC13YWxsaXMgdGVzdA0Ka3J1c2thbF90ZXN0IDwtIGtydXNrYWwudGVzdChgRHVyYXRpb24gKGluIG1pbnMpYCB+IGdyb3VwLCBkYXRhID0gdGltZV9kdXJhdGlvbl90YWJsZSkNCnByaW50KGtydXNrYWxfdGVzdCkNCg0KIyBydW4gcG9zdC1ob2MgdGVzdA0KZHVubl90ZXN0IDwtIGR1bm5UZXN0KGBEdXJhdGlvbiAoaW4gbWlucylgIH4gZ3JvdXAsIGRhdGEgPSB0aW1lX2R1cmF0aW9uX3RhYmxlLCBtZXRob2QgPSAiYm9uZmVycm9uaSIpDQpwcmludChkdW5uX3Rlc3QpDQoNCmBgYA0KDQpUaW1lIGR1cmF0aW9uIHN1bW1hcnkgdGFibGUNCg0KYGBge3J9DQp0aW1lX2R1cmF0aW9uX3N1bW1hcnkgPC0gdGltZV9kdXJhdGlvbl90YWJsZSAlPiUNCiAgZ3JvdXBfYnkoZ3JvdXApICU+JQ0KICBzdW1tYXJpc2UobWVhbl9kdXJhdGlvbiA9IG1lYW4oYER1cmF0aW9uIChpbiBtaW5zKWAsIG5hLnJtID0gVFJVRSksIA0KICAgICAgICAgICAgc2RfZHVyYXRpb24gPSBzZChgRHVyYXRpb24gKGluIG1pbnMpYCwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgIC5ncm91cHMgPSAnZHJvcCcpDQpgYGANCg0KUGxvdCB0aGUgZGlzdHJpYnV0aW9uIG9mIGRpZmZlcmVudCBncm91cHMNCmBgYHtyfQ0KIyBkZW5zaXR5IHBsb3QNCmdncGxvdCh0aW1lX2R1cmF0aW9uX3RhYmxlLCBhZXMoeCA9IGBEdXJhdGlvbiAoaW4gbWlucylgLCBmaWxsID0gZ3JvdXApKSArDQogIGdlb21fZGVuc2l0eShhbHBoYSA9IDAuMykgKw0KICAjIGZhY2V0X3dyYXAofiBncm91cCwgc2NhbGVzID0gImZyZWUiKSArDQogIGxhYnModGl0bGUgPSAiRHVyYXRpb24gRGVuc2l0eSBieSBHcm91cCIsDQogICAgICAgeCA9ICJEdXJhdGlvbiIsDQogICAgICAgeSA9ICJEZW5zaXR5IikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KDQojIGhpc3RvZ3JhbQ0KZ2dwbG90KHRpbWVfZHVyYXRpb25fdGFibGUsIGFlcyh4ID0gYER1cmF0aW9uIChpbiBtaW5zKWApKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMSwgZmlsbCA9ICJzdGVlbGJsdWUiLCBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgZmFjZXRfd3JhcCh+IGdyb3VwKSArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIER1cmF0aW9uIGJ5IEdyb3VwIiwNCiAgICAgICB4ID0gIkR1cmF0aW9uIChlLmcuIGluIG1pbnV0ZXMpIiwNCiAgICAgICB5ID0gIkNvdW50IikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIG1heCh0aW1lX2R1cmF0aW9uX3RhYmxlJGBEdXJhdGlvbiAoaW4gbWlucylgLCBuYS5ybSA9IFRSVUUpLCBieSA9IDEwKSkgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQoNCg0KUGxvdCB0aW1lIGR1cmF0aW9uIGJhciBjaGFydC4gSXQncyBub3QgdmFsaWQgYXMgdGhlIGRhdGEgaXMgbm90IG5vcm1hbCBkaXN0cmlidXRpb24uDQoNCmBgYHtyfQ0KZ2dwbG90KHRpbWVfZHVyYXRpb25fc3VtbWFyeSwgYWVzKHggPSBncm91cCwgeSA9IG1lYW5fZHVyYXRpb24pKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gInN0ZWVsYmx1ZSIsIHdpZHRoID0gMC42KSArDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtZWFuX2R1cmF0aW9uIC0gc2RfZHVyYXRpb24sIHltYXggPSBtZWFuX2R1cmF0aW9uICsgc2RfZHVyYXRpb24pLCB3aWR0aCA9IDAuMikgKw0KICBsYWJzKHRpdGxlID0gIlJlc3BvbnNlIER1cmF0aW9uIGJ5IEdyb3VwIiwNCiAgICAgICB5ID0gIkR1cmF0aW9uIChpbiBtaW51dGVzKSIsDQogICAgICAgeCA9ICJHcm91cCIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KIyMgUTMuMiBBZ2UNCldoYXQgaXMgeW91ciBhZ2U/IDxicj4gDQpWYXJpYWJsZTogY29udGludW91cyA8YnI+IA0KTWV0aG9kOiBrcnVza2FsLXdhbGxpcyB0ZXN0IDxicj4gDQoqKlJlc3VsdDogRmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyoqDQpgYGB7cn0NCmFnZV90YWJsZSA8LSByYXdkYXRhX3ZhbHVlWywgYygiUTMuMiIsICJncm91cCIpXQ0KYWdlX3RhYmxlJGBRMy4yYCA8LSBhcy5udW1lcmljKGdzdWIoIlteMC05Ll0iLCAiIiwgYWdlX3RhYmxlJGBRMy4yYCkpDQoNCiMgdGVzdCBmb3Igbm9ybWFsaXR5DQojIHNoYXBpcm8udGVzdChhZ2VfdGFibGUkYFEzLjJgKQ0KIyBiYXJ0bGV0dC50ZXN0KGBRMy4yYCB+IGdyb3VwLCBkYXRhID0gYWdlX3RhYmxlKQ0KDQoNCiMgcnVuIHRoZSBrcnVza2FsLXdhbGxpcyB0ZXN0DQprcnVza2FsX3Rlc3QgPC0ga3J1c2thbC50ZXN0KGBRMy4yYCB+IGdyb3VwLCBkYXRhID0gYWdlX3RhYmxlKQ0KcHJpbnQoa3J1c2thbF90ZXN0KQ0KDQphZ2Vfc3VtbWFyeSA8LSBhZ2VfdGFibGUgJT4lDQogIGdyb3VwX2J5KGdyb3VwKSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5fYWdlID0gbWVhbihgUTMuMmAsIG5hLnJtID0gVFJVRSksIA0KICAgICAgICAgICAgc2RfYWdlID0gc2QoYFEzLjJgLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgLmdyb3VwcyA9ICdkcm9wJykNCmBgYA0KDQojIyBRMy4zIEdlbmRlcg0KV2hpY2ggb2YgdGhlIGZvbGxvd2luZyBiZXN0IGRlc2NyaWJlcyB5b3VyIGdlbmRlciBpZGVudGl0eT8gPGJyPiANClZhcmlhYmxlOiBjYXRlZ29yaWNhbCA8YnI+IA0KTWV0aG9kOiBjb250aW5nZW5jeSBUYWJsZSArIGNoaS1zcXVhcmVkIHRlc3QgPGJyPiANCioqUmVzdWx0OiBGYWlsIHRvIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzKioNCmBgYHtyfQ0KcTNfM190YWJsZSA8LSByYXdkYXRhX3ZhbHVlWywgYygiUTMuMyIsICJncm91cCIpXQ0KIyBxM18zX3RhYmxlJFEzLjMgPC0gcmVjb2RlKHEzXzNfdGFibGUkUTMuMywNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEiID0gIk1hbGUiLA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMiIgPSAiRmVtYWxlIiwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmRlZmF1bHQgPSAiT3RoZXIiKQ0KcTNfM19jb250aW5nZW5jeSA8LSB0YWJsZShxM18zX3RhYmxlJFEzLjMsIHEzXzNfdGFibGUkZ3JvdXApDQpwcmludChxM18zX2NvbnRpbmdlbmN5KQ0KDQojIENoaS1zcXVhcmVkIHRlc3QNCmNoaXNxLnRlc3QocTNfM19jb250aW5nZW5jeSkNCg0KYGBgDQoNCkNhbGN1bGF0ZSB0aGUgZ2VuZGVyIHBlcmNlbnRhZ2UNCg0KYGBge3J9DQojIHBlcmNlbnRhZ2Ugb2YgbWFsZQ0KbWFsZV9wZXIgPC0gcTNfM19jb250aW5nZW5jeVsxLF0NCmdlbmRlcl9ncm91cF90b3RhbCA8LSBjb2xTdW1zKHEzXzNfY29udGluZ2VuY3kpDQptYWxlX3Byb3AgPC0gbWFsZV9wZXIvZ2VuZGVyX2dyb3VwX3RvdGFsDQoNCmBgYA0KDQojIyBRMy40IEhpZ2hlc3QgRWR1Y2F0aW9uDQpXaGF0IGlzIHlvdXIgaGlnaGVzdCBsZXZlbCBvZiBlZHVjYXRpb24gYWNoaWV2ZWQ/XA0KVmFyaWFibGU6IGNhdGVnb3JpY2FsIHdpdGggd3JpdHRlbiBpbnNpZ2h0cyBmcm9tIGNob2ljZSA5DQpNZXRob2Q6IGNvbnRpbmdlbmN5IFRhYmxlICsgY2hpLXNxdWFyZWQgdGVzdFwNCioqUmVzdWx0OiBGYWlsIHRvIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzKioNCg0KYGBge3J9DQpxM180X3RhYmxlIDwtIHJhd2RhdGFfdmFsdWVbcmF3ZGF0YV92YWx1ZSRgUTMuNGAgIT0gIjkiLCBjKCJRMy40IiwgImdyb3VwIildDQoNCnEzXzRfY29udGluZ2VuY3kgPC0gdGFibGUocTNfNF90YWJsZSRRMy40LCBxM180X3RhYmxlJGdyb3VwKQ0KIyBDaGktc3F1YXJlZCB0ZXN0DQpjaGlzcS50ZXN0KHEzXzRfY29udGluZ2VuY3kpDQoNCmBgYA0KSGlnaGVzdCBFZHVjYXRpb24gTGV2ZWwgcHJvcG9ydGlvbiBiYXIgcGxvdCBhY3Jvc3MgZGlmZmVyZW50IGdyb3Vwcw0KYGBge3J9DQoNCnEzXzRfcHJvcCAgPC0gYXMuZGF0YS5mcmFtZShxM180X2NvbnRpbmdlbmN5KQ0KIyByZW5hbWUgY29sdW1ucw0KbmFtZXMocTNfNF9wcm9wKSA8LSBjKCJRMy40IiwgIkdyb3VwIiwgIkNvdW50IikNCg0KIyBjYWxjdWxhdGUgcHJvcG9ydGlvbnMgd2l0aGluIGVhY2ggZ3JvdXANCnEzXzRfcHJvcCA8LSBxM180X3Byb3AgJT4lDQogIGdyb3VwX2J5KEdyb3VwKSAlPiUNCiAgbXV0YXRlKFByb3BvcnRpb24gPSBDb3VudCAvIHN1bShDb3VudCkpDQoNCmdncGxvdChxM180X3Byb3AsIGFlcyh4ID0gYXMuZmFjdG9yKGBRMy40YCksIHkgPSBQcm9wb3J0aW9uLCBmaWxsID0gR3JvdXApKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgIyBmYWNldF93cmFwKH4gR3JvdXApICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJRMy40IEhpZ2hlc3QgRWR1Y2F0aW9uIExldmVsIFByb3BvdGlvbiBQbG90IGFjcm9zcyBHcm91cHMiLA0KICAgIHggPSAiUmVzcG9uc2UiLA0KICAgIHkgPSAiUHJvcG9ydGlvbiINCiAgKSArDQogICMgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKA0KICAjICAgIjEiID0gIk5vIGZvcm1hbCBlZHVjYXRpb24iLA0KICAjICAgIjIiID0gIlByaW1hcnkvRWxlbWVudGFyeSIsDQogICMgICAiMyIgPSAiU2Vjb25kYXJ5IFNjaG9vbCAoR0NTRSkiLA0KICAjICAgIjQiID0gIkhpZ2ggU2Nob29sIChBIExldmVsKSIsDQogICMgICAiNSIgPSAiVGVjaG5pY2FsIG9yIFZvY2F0aW9uYWwiLA0KICAjICAgIjYiID0gIkJhY2hlbG9ycyBvciBlcXVpdmFsZW50IGRlZ3JlZSBsZXZlbCBxdWFsaWZpY2F0aW9uIiwNCiAgIyAgICI3IiA9ICJNYXN0ZXJzIG9yIGVxdWl2YWxlbnQgaGlnaGVyIGRlZ3JlZSBsZXZlbCBxdWFsaWZpY2F0aW9uIiwNCiAgIyAgICI4IiA9ICJQaEQgb3IgZXF1aXZhbGVudCBkb2N0b3JhbCBsZXZlbCBxdWFsaWZpY2F0aW9uIikpKw0KICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIikrDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQpQbG90IHBpZSBjaGFydCBpbmNsdWRpbmcgYWxsIHBhcnRpY2lwYW50cw0KYGBge3J9DQpxM180X3RhYmxlIDwtIHJhd2RhdGFfdmFsdWVbLCBjKCJRMy40IiwgImdyb3VwIildDQoNCiMgUTMuNCBzdW1tYXJ5IHRhYmxlDQpxM180X3N1bW1hcnkgPC0gcTNfNF90YWJsZSAlPiUNCiAgZ3JvdXBfYnkoYFEzLjRgKSAlPiUNCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBjb3VudCAvIHN1bShjb3VudCksDQogICAgICAgICBsYWJlbCA9IA0KICAgICAgICAgICAgY2FzZV93aGVuKA0KICAgICAgICAgICAgICBRMy40ID09ICIxIiB+ICIxLU5vIGZvcm1hbCBlZHVjYXRpb24iLA0KICAgICAgICAgICAgICBRMy40ID09ICIyIiB+ICIyLVByaW1hcnkvRWxlbWVudGFyeSIsDQogICAgICAgICAgICAgIFEzLjQgPT0gIjMiIH4gIjMtU2Vjb25kYXJ5IFNjaG9vbCAoR0NTRSkiLA0KICAgICAgICAgICAgICBRMy40ID09ICI0IiB+ICI0LUhpZ2ggU2Nob29sIChBIExldmVsKSIsDQogICAgICAgICAgICAgIFEzLjQgPT0gIjUiIH4gIjUtVGVjaG5pY2FsIG9yIFZvY2F0aW9uYWwiLA0KICAgICAgICAgICAgICBRMy40ID09ICI2IiB+ICI2LUJhY2hlbG9ycyBvciBlcXVpdmFsZW50IGRlZ3JlZSBsZXZlbCBxdWFsaWZpY2F0aW9uIiwNCiAgICAgICAgICAgICAgUTMuNCA9PSAiNyIgfiAiNy1NYXN0ZXJzIG9yIGVxdWl2YWxlbnQgaGlnaGVyIGRlZ3JlZSBsZXZlbCBxdWFsaWZpY2F0aW9uIiwNCiAgICAgICAgICAgICAgUTMuNCA9PSAiOCIgfiAiOC1QaEQgb3IgZXF1aXZhbGVudCBkb2N0b3JhbCBsZXZlbCBxdWFsaWZpY2F0aW9uIiwNCiAgICAgICAgICAgICAgUTMuNCA9PSAiOSIgfiAiOS1PdGhlciINCiAgICAgICAgICAgICksDQogICAgICAgICBsYWJlbCA9IHBhc3RlMChsYWJlbCwgIiAoIiwgcm91bmQocHJvcG9ydGlvbiAqIDEwMCwgMiksICIgJSkiKQ0KICAgICAgICAgKQ0KDQpnZ3Bsb3QocTNfNF9zdW1tYXJ5LCBhZXMoeCA9ICIiLHkgPSBwcm9wb3J0aW9uLCBmaWxsID0gbGFiZWwpKSArDQogIGdlb21fY29sKHdpZHRoID0gMSkgKw0KICBjb29yZF9wb2xhcih0aGV0YSA9ICJ5IikgKw0KICBsYWJzKHRpdGxlID0gIlEzLjQgSGlnaGVzdCBFZHVjYXRpb24gTGV2ZWwgU3VtbWFyeSBQaWUgQ2hhcnQiLA0KICAgICAgIHggPSAiIiwNCiAgICAgICB5ID0gIiIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpDQoNCmBgYA0KDQoNCg0KIyMgUTMuNSBFbXBsb3llZSBTdGF0dXMNCldoYXQgaXMgeW91ciBjdXJyZW50IHByb2Zlc3Npb24gb3IgZW1wbG95bWVudCBzdGF0dXM/XA0KVmFyaWFibGU6IGNhdGVnb3JpY2FsXA0KTWV0aG9kOiBjb250aW5nZW5jeSBUYWJsZSArIGNoaS1zcXVhcmVkIHRlc3RcDQoqKlJlc3VsdDogRmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyoqDQpgYGB7cn0NCnEzXzVfdGFibGUgPC0gcmF3ZGF0YV92YWx1ZVtyYXdkYXRhX3ZhbHVlJGBRMy41YCAhPSAiNiIsIGMoIlEzLjUiLCAiZ3JvdXAiKV0NCnEzXzVfY29udGluZ2VuY3kgPC0gdGFibGUocTNfNV90YWJsZSRRMy41LCBxM181X3RhYmxlJGdyb3VwKQ0KIyBwcmludChxM181X2NvbnRpbmdlbmN5KQ0KDQojIENoaS1zcXVhcmVkIHRlc3QNCmNoaXNxLnRlc3QocTNfNV9jb250aW5nZW5jeSkNCg0KYGBgDQoNCkVtcGxveWVlIHN0YXR1cyBwcm9wb3J0aW9uIGJhciBwbG90IGFjcm9zcyBkaWZmZXJlbnQgZ3JvdXBzDQoNCmBgYHtyfQ0KcTNfNV9wcm9wICA8LSBhcy5kYXRhLmZyYW1lKHEzXzVfY29udGluZ2VuY3kpDQojIHJlbmFtZSBjb2x1bW5zDQpuYW1lcyhxM181X3Byb3ApIDwtIGMoIlEzLjUiLCAiR3JvdXAiLCAiQ291bnQiKQ0KDQoNCiMgY2FsY3VsYXRlIHByb3BvcnRpb25zIHdpdGhpbiBlYWNoIGdyb3VwDQpxM181X3Byb3AgPC0gcTNfNV9wcm9wICU+JQ0KICBncm91cF9ieShHcm91cCkgJT4lDQogIG11dGF0ZShQcm9wb3J0aW9uID0gQ291bnQgLyBzdW0oQ291bnQpKQ0KDQpnZ3Bsb3QocTNfNV9wcm9wLCBhZXMoeCA9IGFzLmZhY3RvcihgUTMuNWApLCB5ID0gUHJvcG9ydGlvbiwgZmlsbCA9IEdyb3VwKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiKSArDQogICMgZmFjZXRfd3JhcCh+IEdyb3VwKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUTMuNSBFbXBsb3llZSBTdGF0dXMgUHJvcG90aW9uIFBsb3QgYWNyb3NzIEdyb3VwcyIsDQogICAgeCA9ICJSZXNwb25zZSIsDQogICAgeSA9ICJQcm9wb3J0aW9uIg0KICApICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKA0KICAgICIxIiA9ICJTdHVkZW50IiwNCiAgICAiMiIgPSAiRW1wbG95ZWQiLA0KICAgICIzIiA9ICJTZWxmLWVtcGxveWVkIiwNCiAgICAiNCIgPSAiUmV0aXJlZCIsDQogICAgIjUiID0gIlVuZW1wbG95ZWQiDQogICkpICsNCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANCg0KUGxvdCBwaWUgY2hhcnQgaW5jbHVkaW5nIGFsbCBwYXJ0aWNpcGFudHMNCmBgYHtyfQ0KcTNfNV90YWJsZSA8LSByYXdkYXRhX3ZhbHVlWywgYygiUTMuNSIsICJncm91cCIpXQ0KcTNfNV9zdW1tYXJ5IDwtIHEzXzVfdGFibGUgJT4lDQogIGdyb3VwX2J5KGBRMy41YCkgJT4lDQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lDQogIG11dGF0ZShwcm9wb3J0aW9uID0gY291bnQgLyBzdW0oY291bnQpLA0KICAgICAgICAgbGFiZWwgPSANCiAgICAgICAgICAgIGNhc2Vfd2hlbigNCiAgICAgICAgICAgICAgUTMuNSA9PSAiMSIgfiAiMS1TdHVkZW50IiwNCiAgICAgICAgICAgICAgUTMuNSA9PSAiMiIgfiAiMi1FbXBsb3llZCIsDQogICAgICAgICAgICAgIFEzLjUgPT0gIjMiIH4gIjMtU2VsZi1lbXBsb3llZCIsDQogICAgICAgICAgICAgIFEzLjUgPT0gIjQiIH4gIjQtUmV0aXJlZCIsDQogICAgICAgICAgICAgIFEzLjUgPT0gIjUiIH4gIjUtVW5lbXBsb3llZCIsDQogICAgICAgICAgICAgIFEzLjUgPT0gIjYiIH4gIjYtT3RoZXIiDQogICAgICAgICAgICApLA0KICAgICAgICAgbGFiZWwgPSBwYXN0ZTAobGFiZWwsICIgKCIsIHJvdW5kKHByb3BvcnRpb24gKiAxMDAsIDIpLCAiICUpIikNCiAgICAgICAgICkNCmdncGxvdChxM181X3N1bW1hcnksIGFlcyh4ID0gIiIseSA9IHByb3BvcnRpb24sIGZpbGwgPSBsYWJlbCkpICsNCiAgZ2VvbV9jb2wod2lkdGggPSAxKSArDQogIGNvb3JkX3BvbGFyKHRoZXRhID0gInkiKSArDQogIGxhYnModGl0bGUgPSAiUTMuNSBFbXBsb3llZSBTdGF0dXMgU3VtbWFyeSBQaWUgQ2hhcnQiLA0KICAgICAgIHggPSAiIiwNCiAgICAgICB5ID0gIiIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpDQpgYGANCg0KDQoNCg0KIyMgUTMuNiBFY29ub21pY3MgRWR1Y2F0aW9uDQpJbiB3aGljaCwgaWYgYW55LCBoYXZlIHlvdSBldmVyIHN0dWRpZWQgZWNvbm9taWNzPyAoU2VsZWN0IGFsbCB0aGF0IGFwcGx5KVwNClZhcmlhYmxlOiBjYXRlZ29yaWNhbFwNCk1ldGhvZDogY29udmVydCB0byBsaXN0IGFuZCBjb3VudCArIGNoaS1zcXVhcmVkIHRlc3RcDQoqKlJlc3VsdDogRmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyoqDQoNCg0KUGxvdCBwZXJjZW50YWdlIGJhciBjaGFydCBpbmNsdWRpbmcgYWxsIHBhcnRpY2lwYW50cw0KYGBge3J9DQpxM182X3RhYmxlIDwtIHJhd2RhdGFfdmFsdWVbLCBjKCJRMy42IiwgImdyb3VwIildDQpxM182X3RhYmxlJFEzLjYgPC0gbGFwcGx5KHEzXzZfdGFibGUkUTMuNiwgZnVuY3Rpb24oeCkgYXMubGlzdChhcy5udW1lcmljKHN0cnNwbGl0KHgsICIsIilbWzFdXSkpKQ0KDQojIGNvdW50IHRoZSBudW1iZXIgb2Ygb2NjdXJyZW5jZXMgb2YgZWFjaCB2YWx1ZQ0KcTNfNl9zdW1tYXJ5IDwtIHEzXzZfdGFibGUgJT4lDQogIHVubmVzdChRMy42KSAlPiUNCiAgZ3JvdXBfYnkoYFEzLjZgKSAlPiUNCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBjb3VudCAvIHRvdGFsX3Jlc3BvbmRlbnRzLA0KICAgICAgICAgbGFiZWwgPSANCiAgICAgICAgICAgIGNhc2Vfd2hlbigNCiAgICAgICAgICAgICAgUTMuNiA9PSAiMSIgfiAiMS1BdCBzY2hvb2wiLA0KICAgICAgICAgICAgICBRMy42ID09ICIyIiB+ICIyLUluIGhpZ2hlciBlZHVjYXRpb24iLA0KICAgICAgICAgICAgICBRMy42ID09ICIzIiB+ICIzLVRocm91Z2ggc2VsZi1kaXJlY3RlZCBzdHVkeSIsDQogICAgICAgICAgICAgIFEzLjYgPT0gIjQiIH4gIjQtU2VsZi1tb3RpdmF0ZWQgc3R1ZHkiLA0KICAgICAgICAgICAgICBRMy42ID09ICI1IiB+ICI1LU5ldmVyIHN0dWRpZWQgZWNvbm9taWNzIiwNCiAgICAgICAgICAgICAgUTMuNiA9PSAiNiIgfiAiNi1Eb27igJl0IGtub3cgLyBjYW7igJl0IHJlY2FsbCIsDQogICAgICAgICAgICAgIFEzLjYgPT0gIjciIH4gIjctT3RoZXIiDQogICAgICAgICAgICApKQ0KDQojIHEzXzZfc3VtbWFyeSRRMy42IDwtIGFzLm51bWVyaWMocTNfNl9zdW1tYXJ5JFEzLjYpDQpnZ3Bsb3QocTNfNl9zdW1tYXJ5LCBhZXMoeCA9IGZhY3RvcihsYWJlbCksIHkgPSBwcm9wb3J0aW9uKSkgKw0KICBnZW9tX2NvbChmaWxsID0gInN0ZWVsYmx1ZSIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChyb3VuZChwcm9wb3J0aW9uICogMTAwLCAxKSwgIiUiKSksIA0KICAgICAgICAgICAgdmp1c3QgPSAtMC4zLCBzaXplID0gMy41KSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJQZXJjZW50YWdlIG9mIFBhcnRpY2lwYW50cyBTZWxlY3RpbmcgRWFjaCBRMy42IE9wdGlvbiIsDQogICAgeCA9ICJSZXNwb25zZSIsDQogICAgeSA9ICJQZXJjZW50YWdlIG9mIFBhcnRpY2lwYW50cyINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQoNCmBgYA0KDQoNCg0KDQoNCmBgYHtyfQ0KcTNfNl90YWJsZSA8LSByYXdkYXRhX3ZhbHVlWywgYygiUTMuNiIsICJncm91cCIpXQ0KcTNfNl90YWJsZSRRMy42IDwtIGxhcHBseShxM182X3RhYmxlJFEzLjYsIGZ1bmN0aW9uKHgpIGFzLmxpc3QoYXMubnVtZXJpYyhzdHJzcGxpdCh4LCAiLCIpW1sxXV0pKSkNCiMgY291bnQgdGhlIG51bWJlciBvZiBvY2N1cnJlbmNlcyBvZiBlYWNoIHZhbHVlDQpxM182X3Byb3AgPC0gcTNfNl90YWJsZSAlPiUNCiAgdW5uZXN0KFEzLjYpICU+JQ0KICBncm91cF9ieShncm91cCwgUTMuNikgJT4lDQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwgLmdyb3VwcyA9ICdkcm9wJykNCnEzXzZfcHJvcCRRMy42IDwtIGFzLm51bWVyaWMocTNfNl9wcm9wJFEzLjYpDQoNCiMgY3JlYXRlIGEgY29udGluZ2VuY3kgdGFibGUNCnEzXzZfY29udGluZ2VuY3kgPC0geHRhYnMoY291bnQgfiBRMy42ICsgZ3JvdXAsIGRhdGEgPSBxM182X3Byb3ApDQpwcmludChxM182X2NvbnRpbmdlbmN5KQ0KDQojIENoaS1zcXVhcmVkIHRlc3QNCmNoaXNxLnRlc3QocTNfNl9jb250aW5nZW5jeSkNCg0KIyBxM182X3Rlc3QgPC1xM182X3Byb3AgJT4lDQojICAgZ3JvdXBfYnkoYFEzLjZgKSAlPiUNCiMgICBzdW1tYXJpc2UodG90YWxfY291bnQgPSBzdW0oY291bnQpLCAuZ3JvdXBzID0gImRyb3AiKQ0KDQpgYGANCg0KRWNvbm9taWNzIEVkdWNhdGlvbiBwcm9wb3J0aW9uIGJhciBwbG90IGFjcm9zcyBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCiMgY29udmVydCBjb250aW5nZW5jeSB0YWJsZSB0byBkYXRhIGZyYW1lICMgY291bnQgMCBhcyB3ZWxsDQpxM182X3Byb3AgPC0gYXMuZGF0YS5mcmFtZShxM182X2NvbnRpbmdlbmN5KQ0KIyBjYWxjdWxhdGUgcHJvcG9ydGlvbnMgd2l0aGluIGVhY2ggZ3JvdXANCnEzXzZfcHJvcCA8LSBxM182X3Byb3AgJT4lDQogIGxlZnRfam9pbihncm91cF90b3RhbCwgYnkgPSAiZ3JvdXAiKSAlPiUNCiAgbXV0YXRlKFByb3BvcnRpb24gPSBGcmVxIC8gbl9yZXNwb25kZW50cykNCg0KZ2dwbG90KHEzXzZfcHJvcCwgYWVzKHggPSBmYWN0b3IoUTMuNiksIHkgPSBQcm9wb3J0aW9uLCBmaWxsID0gZmFjdG9yKGdyb3VwKSkpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUTMuNiBFY29ub21pY3MgRWR1Y2F0aW9uIFByb3BvdGlvbiBQbG90IGFjcm9zcyBHcm91cHMiLA0KICAgIHggPSAiUmVzcG9uc2UiLA0KICAgIHkgPSAiUHJvcG9ydGlvbiIsDQogICAgZmlsbCA9ICJHcm91cCINCiAgKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCg0KDQojIyBRMy43IEZpbmFuY2lhbCBBY3Rpdml0aWVzDQpXaGljaCBvZiB0aGUgZm9sbG93aW5nIGZpbmFuY2lhbCBhY3Rpdml0aWVzIGRvIHlvdSBhY3RpdmVseSBwYXJ0aWNpcGF0ZSBpbj8gKFNlbGVjdCBhbGwgdGhhdCBhcHBseSkgLSBTZWxlY3RlZCBDaG9pY2UgRml4ZWQgSW5jb21lIChlLmcuLCBnb3Zlcm5tZW50IGJvbmRzLCBjb3Jwb3JhdGUgYm9uZHMpXA0KVmFyaWFibGU6IGNhdGVnb3JpY2FsXA0KTWV0aG9kOiBjb252ZXJ0IHRvIGxpc3QgYW5kIGNvdW50ICsgY2hpLXNxdWFyZWQgdGVzdFwNCioqUmVzdWx0OiBGYWlsIHRvIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzKioNCmBgYHtyfQ0KcTNfN190YWJsZSA8LSByYXdkYXRhX3ZhbHVlWywgYygiUTMuNyIsICJncm91cCIpXQ0KcTNfN190YWJsZSRRMy43IDwtIGxhcHBseShxM183X3RhYmxlJFEzLjcsIGZ1bmN0aW9uKHgpIGFzLmxpc3QoYXMubnVtZXJpYyhzdHJzcGxpdCh4LCAiLCIpW1sxXV0pKSkNCiMgY291bnQgdGhlIG51bWJlciBvZiBvY2N1cnJlbmNlcyBvZiBlYWNoIHZhbHVlIGluIGVhY2ggZ3JvdXANCnEzXzdfcHJvcCA8LSBxM183X3RhYmxlICU+JQ0KICB1bm5lc3QoUTMuNykgJT4lDQogIGdyb3VwX2J5KGdyb3VwLGBRMy43YCkgJT4lDQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwgLmdyb3VwcyA9ICdkcm9wJykNCnEzXzdfcHJvcCRRMy43IDwtIGFzLm51bWVyaWMocTNfN19wcm9wJFEzLjcpDQoNCiMgY3JlYXRlIGEgY29udGluZ2VuY3kgdGFibGUNCnEzXzdfY29udGluZ2VuY3kgPC0geHRhYnMoY291bnQgfiBgUTMuN2AgKyBncm91cCwgZGF0YSA9IHEzXzdfcHJvcCkNCnByaW50KHEzXzdfY29udGluZ2VuY3kpDQojIENoaS1zcXVhcmVkIHRlc3QNCmNoaXNxLnRlc3QocTNfN19jb250aW5nZW5jeSkNCg0KYGBgDQoNClBsb3QgZmluYW5jaWFsIGFjdGl2aXRpZXMgcHJvcG9ydGlvbiBiYXIgcGxvdCBhY3Jvc3MgZGlmZmVyZW50IGdyb3Vwcw0KYGBge3J9DQojIGNvbnZlcnQgY29udGluZ2VuY3kgdGFibGUgdG8gZGF0YSBmcmFtZQ0KcTNfN19wcm9wIDwtIGFzLmRhdGEuZnJhbWUocTNfN19jb250aW5nZW5jeSkgJT4lDQogIGxlZnRfam9pbihncm91cF90b3RhbCwgYnkgPSAiZ3JvdXAiKSAlPiUNCiAgbXV0YXRlKFByb3BvcnRpb24gPSBGcmVxIC8gbl9yZXNwb25kZW50cykNCg0KDQpnZ3Bsb3QocTNfN19wcm9wLCBhZXMoeCA9IGZhY3RvcihgUTMuN2ApLCB5ID0gUHJvcG9ydGlvbiwgZmlsbCA9IGZhY3Rvcihncm91cCkpKSArIA0KICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJRMy43IEZpbmFuY2lhbCBBY3Rpdml0aWVzIFByb3BvdGlvbiBQbG90IGFjcm9zcyBHcm91cHMiLA0KICAgIHggPSAiUmVzcG9uc2UiLA0KICAgIHkgPSAiUHJvcG9ydGlvbiIsDQogICAgZmlsbCA9ICJHcm91cCINCiAgKSArDQogICAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKA0KICAgICIxMSIgPSAiU2F2aW5ncyIsDQogICAgIjEyIiA9ICJJbnZlc3RtZW50cyIsDQogICAgIjEzIiA9ICJGaXhlZCBJbmNvbWUiLA0KICAgICIxNCIgPSAiUmV0aXJlbWVudCBQbGFubmluZyIsDQogICAgIjE1IiA9ICJUcmFkaW5nIiwNCiAgICAiMTYiID0gIlJlYWwgRXN0YXRlIiwNCiAgICAiMTciID0gIkNyeXB0b2N1cnJlbmNpZXMiLA0KICAgICIxOCIgPSAiTm9uZSBvZiB0aGUgYWJvdmUiLA0KICAgICIxOSIgPSAiT3RoZXIiDQogICAgICApKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQoNCmBgYA0KUGxvdCBwZXJjZW50YWdlIGJhciBjaGFydCBpbmNsdWRpbmcgYWxsIHBhcnRpY2lwYW50cw0KYGBge3J9DQpxM183X3N1bW1hcnkgPC1xM183X3Byb3AgJT4lDQogIGdyb3VwX2J5KGBRMy43YCkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9jb3VudCA9IHN1bShGcmVxKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIG11dGF0ZShwcm9wb3J0aW9uID0gdG90YWxfY291bnQgLyB0b3RhbF9yZXNwb25kZW50cywNCiAgICAgICAgIGxhYmVsID0gDQogICAgICAgICAgICBjYXNlX3doZW4oDQogICAgICAgICAgICAgIGBRMy43YCA9PSAiMTEiIH4gIjExLVNhdmluZ3MiLA0KICAgICAgICAgICAgICBgUTMuN2AgPT0gIjEyIiB+ICIxMi1JbnZlc3RtZW50cyIsDQogICAgICAgICAgICAgIGBRMy43YCA9PSAiMTMiIH4gIjEzLUZpeGVkIEluY29tZSIsDQogICAgICAgICAgICAgIGBRMy43YCA9PSAiMTQiIH4gIjE0LVJldGlyZW1lbnQgUGxhbm5pbmciLA0KICAgICAgICAgICAgICBgUTMuN2AgPT0gIjE1IiB+ICIxNS1UcmFkaW5nIiwNCiAgICAgICAgICAgICAgYFEzLjdgID09ICIxNiIgfiAiMTYtUmVhbCBFc3RhdGUiLA0KICAgICAgICAgICAgICBgUTMuN2AgPT0gIjE3IiB+ICIxNy1DcnlwdG9jdXJyZW5jaWVzIiwNCiAgICAgICAgICAgICAgYFEzLjdgID09ICIxOCIgfiAiMTgtTm9uZSBvZiB0aGUgYWJvdmUiLA0KICAgICAgICAgICAgICBgUTMuN2AgPT0gIjE5IiB+ICIxOS1PdGhlciINCiAgICAgICAgICAgICkpDQoNCmdncGxvdChxM183X3N1bW1hcnksIGFlcyh4ID0gZmFjdG9yKGxhYmVsKSwgeSA9IHByb3BvcnRpb24pKSArDQogIGdlb21fY29sKGZpbGwgPSAic3RlZWxibHVlIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUwKHJvdW5kKHByb3BvcnRpb24gKiAxMDAsIDEpLCAiJSIpKSwgDQogICAgICAgICAgICB2anVzdCA9IC0wLjMsIHNpemUgPSAzLjUpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlBlcmNlbnRhZ2Ugb2YgUGFydGljaXBhbnRzIFNlbGVjdGluZyBFYWNoIFEzLjcgT3B0aW9uIiwNCiAgICB4ID0gIlJlc3BvbnNlIiwNCiAgICB5ID0gIlBlcmNlbnRhZ2Ugb2YgUGFydGljaXBhbnRzIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KYGBgDQojIyBRMy44IEF3YXJlbmVzcyBvZiBFY29ub21pY3MNCkhvdyBmcmVxdWVudGx5LCBpZiBhdCBhbGwsIGRvIHlvdSByZWFkL3dhdGNoL2xpc3RlbiB0byBuZXdzIHN0b3JpZXMgcmVsYXRlZCB0byBlY29ub21pY3Mgb3IgdGhlIGVjb25vbXk/XA0KVmFyaWFibGU6IGNhdGVnb3JpY2FsXA0KTWV0aG9kOiBjb250aW5nZW5jeSB0YWJsZSArIGNoaS1zcXVhcmVkIHRlc3RcDQoqKlJlc3VsdDogRmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyoqDQpgYGB7cn0NCnEzXzhfdGFibGUgPC0gcmF3ZGF0YV92YWx1ZVssIGMoIlEzLjgiLCAiZ3JvdXAiKV0NCg0KcTNfOF9jb250aW5nZW5jeSA8LSB0YWJsZShxM184X3RhYmxlJFEzLjgsIHEzXzhfdGFibGUkZ3JvdXApDQpwcmludChxM184X2NvbnRpbmdlbmN5KQ0KIyBDaGktc3F1YXJlZCB0ZXN0DQojIGNoaXNxLnRlc3QocTNfOF9jb250aW5nZW5jeSkNCmNoaXNxLnRlc3QocTNfOF9jb250aW5nZW5jeVstbnJvdyhxM184X2NvbnRpbmdlbmN5KSwgXSkNCg0KYGBgDQpBd2FyZW5lc3Mgb2YgRWNvbm9taWNzIHByb3BvcnRpb24gYmFyIHBsb3QgYWNyb3NzIGRpZmZlcmVudCBncm91cHMNCmBgYHtyfQ0KcTNfOF9wcm9wICA8LSBhcy5kYXRhLmZyYW1lKHEzXzhfY29udGluZ2VuY3kpDQojIHJlbmFtZSBjb2x1bW5zDQpuYW1lcyhxM184X3Byb3ApIDwtIGMoIlEzLjgiLCAiR3JvdXAiLCAiQ291bnQiKQ0KDQojIGFkZCBhIGxhYmVsbGVkIGNvbHVtbg0KcTNfOF9wcm9wIDwtIHEzXzhfcHJvcCAlPiUNCiAgbXV0YXRlKFEzLjhfbGFiZWwgPSBjYXNlX3doZW4oDQogICAgUTMuOCA9PSAiMSIgfiAiMS1OZXZlciIsDQogICAgUTMuOCA9PSAiMiIgfiAiMi1SYXJlbHkiLA0KICAgIFEzLjggPT0gIjMiIH4gIjMtTW9udGhseSIsDQogICAgUTMuOCA9PSAiNCIgfiAiNC1XZWVrbHkiLA0KICAgIFEzLjggPT0gIjUiIH4gIjUtQWxtb3N0IGRhaWx5IiwNCiAgICBRMy44ID09ICI2IiB+ICI2LUV2ZXJ5IGRheSIsDQogICAgUTMuOCA9PSAiNyIgfiAiNy1Ob3Qgc3VyZSINCiAgKSkNCg0KIyBjYWxjdWxhdGUgcHJvcG9ydGlvbnMgd2l0aGluIGVhY2ggZ3JvdXANCnEzXzhfcHJvcCA8LSBxM184X3Byb3AgJT4lDQogIGdyb3VwX2J5KEdyb3VwKSAlPiUNCiAgbXV0YXRlKFByb3BvcnRpb24gPSBDb3VudCAvIHN1bShDb3VudCkpDQoNCmdncGxvdChxM184X3Byb3AsIGFlcyh4ID0gYXMuZmFjdG9yKGBRMy44X2xhYmVsYCksIHkgPSBQcm9wb3J0aW9uLCBmaWxsID0gR3JvdXApKSArDQogIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICAjIGZhY2V0X3dyYXAofiBHcm91cCkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlEzLjggQXdhcmVuZXNzIG9mIEVjb25vbWljcyBQcm9wb3Rpb24gUGxvdCBhY3Jvc3MgR3JvdXBzIiwNCiAgICB4ID0gIlJlc3BvbnNlIiwNCiAgICB5ID0gIlByb3BvcnRpb24iDQogICkgKw0KICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIikrDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQoNClBsb3QgcGllIGNoYXJ0IGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCnEzXzhfc3VtbWFyeSA8LSBxM184X3Byb3AgJT4lDQogIGdyb3VwX2J5KGBRMy44X2xhYmVsYCkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9jb3VudCA9IHN1bShDb3VudCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IHRvdGFsX2NvdW50IC8gc3VtKHRvdGFsX2NvdW50KSwNCiAgICAgICAgYFEzLjhfbGFiZWxgID0gcGFzdGUwKGBRMy44X2xhYmVsYCwgIiAoIiwgcm91bmQocHJvcG9ydGlvbiAqIDEwMCwgMiksICIgJSkiKSkNCmdncGxvdChxM184X3N1bW1hcnksIGFlcyh4ID0gIiIseSA9IHByb3BvcnRpb24sIGZpbGwgPSBgUTMuOF9sYWJlbGApKSArDQogIGdlb21fY29sKHdpZHRoID0gMSkgKw0KICBjb29yZF9wb2xhcih0aGV0YSA9ICJ5IikgKw0KICBsYWJzKHRpdGxlID0gIlEzLjggQXdhcmVuZXNzIG9mIEVjb25vbWljcyBTdW1tYXJ5IFBpZSBDaGFydCIsDQogICAgICAgeCA9ICIiLA0KICAgICAgIHkgPSAiIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSkNCmBgYA0KIyMgUTMuOSBJbmZsYXRpb24gS25vd2xlZGdlDQpUbyB0aGUgYmVzdCBvZiB5b3VyIGtub3dsZWRnZSwgd2hpY2ggb3B0aW9uIG1vc3QgYWNjdXJhdGVseSBkZXNjcmliZXMgd2hhdCBpbmZsYXRpb24gaXM/XA0KRGVmaW5pdGl2ZSBjb3JyZWN0IGFuc3dlclwNClZhcmlhYmxlOiBjYXRlZ29yaWNhbFwNCk1ldGhvZDogZGVzY3JpcHRpdmUgYW5hbHlzaXNcDQoqKlJlc3BvbmRlbnRzIHdlcmUgZmlsdGVyZWQgYmFzZWQgb24gd2hldGhlciBpZiB0aGV5IGNhbiB1bmRlcnN0YW5kIHdoYXQgaW5mbGF0aW9uIGlzLioqXA0KDQpgYGB7cn0NCnEzXzlfdGFibGUgPC0gcmF3ZGF0YV9xM185WywgYygiUTMuOSIsICJncm91cCIpXQ0KcTNfOV9zdW1tYXJ5IDwtIHEzXzlfdGFibGUgJT4lDQogIGdyb3VwX2J5KGBRMy45YCkgJT4lDQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lDQogIG11dGF0ZShwcm9wb3J0aW9uID0gY291bnQgLyBzdW0oY291bnQpKQ0KDQogIGdncGxvdChxM185X3N1bW1hcnksIGFlcyh4ID0gIiIseSA9IHByb3BvcnRpb24sIGZpbGwgPSBgUTMuOWApKSArDQogIGdlb21fY29sKHdpZHRoID0gMSkgKw0KICBjb29yZF9wb2xhcih0aGV0YSA9ICJ5IikgKw0KICBsYWJzKHRpdGxlID0gIlEzLjkgSW5mbGF0aW9uIEtub3dsZWRnZSBTdW1tYXJ5IFBpZSBDaGFydCIsDQogICAgICAgeCA9ICIiLA0KICAgICAgIHkgPSAiIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSkNCg0KYGBgDQoNCiMjIFEzLjExIFRydXN0IG9mIE9mZmljaWFsIERhdGENCkhvdyBtdWNoIGRvIHlvdSB0cnVzdCBvZmZpY2lhbCBpbmZsYXRpb24gZm9yZWNhc3RzIChGb3IgaW5zdGFuY2UsIHRoZSBmb3JlY2FzdHMgcmVsZWFzZWQgYnkgdGhlIEJhbmsgb2YgRW5nbGFuZCk/XA0KKmFzY2VuZGluZyB2YWx1ZS1pbmNyZWFzaW5nIHRydXN0ICsgZXhjbHVkZSA2LSBVbnN1cmUgLyBubyBvcGluaW9uKlwNClZhcmlhYmxlOiB0cmVhdCBhcyBjb250aW51b3VzXA0KTWV0aG9kOiBLcnVza2FsLVdhbGxpcyB0ZXN0XA0KKipSZXN1bHQ6IEZhaWwgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMqKg0KDQpgYGB7cn0NCnEzXzExX3RhYmxlIDwtIHJhd2RhdGFfdmFsdWVbcmF3ZGF0YV92YWx1ZSRgUTMuMTFgICE9ICI2IiwgYygiUTMuMTEiLCAiZ3JvdXAiKV0NCnEzXzExX3RhYmxlJFEzLjExIDwtIGFzLm51bWVyaWMocTNfMTFfdGFibGUkYFEzLjExYCkNCiMgY2hlY2sgbm9ybWFsaXR5IC0tPiBOb3Qgbm9ybWFsbHkgZGlzdHJpYnV0ZWQNCiMgc2hhcGlyby50ZXN0KHEzXzExX3RhYmxlJFEzLjExKQ0KIyBiYXJ0bGV0dC50ZXN0KGBRMy4xMWAgfiBncm91cCwgZGF0YSA9IHEzXzExX3RhYmxlKQ0KDQoNCiMgcnVuIGtydXNrYWwgdGVzdA0Ka3J1c2thbF90ZXN0IDwtIGtydXNrYWwudGVzdChRMy4xMSB+IGdyb3VwLCBkYXRhID0gcTNfMTFfdGFibGUpDQpwcmludChrcnVza2FsX3Rlc3QpDQoNCnEzXzExX3N1bW1hcnkgPC0gcTNfMTFfdGFibGUgJT4lDQogIGdyb3VwX2J5KGdyb3VwKSAlPiUNCiAgc3VtbWFyaXNlKHEzXzExX21lYW4gPSBtZWFuKGFzLm51bWVyaWMoUTMuMTEpLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgcTNfMTFfc2QgPSBzZChhcy5udW1lcmljKFEzLjExKSwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgIC5ncm91cHMgPSAnZHJvcCcpDQoNCiMgcmVwb3J0IHF1YW50aWxlIGluZm9ybWF0aW9uDQpzdW1tYXJ5KHEzXzExX3RhYmxlJFEzLjExKQ0KDQoNCg0KYGBgDQpQbG90IHRoZSBkaXN0cmlidXRpb24gb2YgZGlmZmVyZW50IGdyb3Vwcw0KYGBge3J9DQojIGhpc3RvZ3JhbSBpbmNsdWRpbmcgYWxsIHBhcnRpY2lwYW50cw0KZ2dwbG90KHEzXzExX3RhYmxlLCBhZXMoeCA9IFEzLjExKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEsIGZpbGwgPSAic3RlZWxibHVlIiwgY29sb3IgPSAid2hpdGUiKSArDQogICMgZmFjZXRfd3JhcCh+IGdyb3VwKSArDQogIGxhYnModGl0bGUgPSAiUTMuMTEgVHJ1c3Qgb2ZmaWNpYWwgaW5mbGF0aW9uIGZvcmVjYXN0cyBkaXN0cmlidXRpb24iLA0KICAgICAgIHggPSAiUTMuMTEiLA0KICAgICAgIHkgPSAiQ291bnQiKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgbWF4KHEzXzExX3RhYmxlJFEzLjExLCBuYS5ybSA9IFRSVUUpLCBieSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQojIEdyb3VwZWQgYmFyLXN0eWxlIGhpc3RvZ3JhbQ0KZ2dwbG90KHEzXzExX3RhYmxlLCBhZXMoeCA9IGZhY3RvcihRMy4xMSksIGZpbGwgPSBmYWN0b3IoZ3JvdXApKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJRMy4xMSBUcnVzdCBvZmZpY2lhbCBpbmZsYXRpb24gZm9yZWNhc3RzIGRpc3RyaWJ1dGlvbiBieSBncm91cCIsDQogICAgeCA9ICJRMy4xMSBSZXNwb25zZSIsDQogICAgeSA9ICJDb3VudCIsDQogICAgZmlsbCA9ICJHcm91cCINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpgYGANCg0KDQoNCiANCg0KDQojIyBRMy4xMiBGcmVxdWVuY3kgb2YgQ2hlY2tpbmcgQ3VycmVudCBJbmZsYXRpb24NCkhvdyBvZnRlbiBkbyB5b3UgY2hlY2sgdGhlIGN1cnJlbnQgdmFsdWUgb2YgaW5mbGF0aW9uPw0KVmFyaWFibGU6IGNhdGVnb3JpY2FsXA0KTWV0aG9kOiBjb250aW5nZW5jeSB0YWJsZSArIGNoaS1zcXVhcmVkIHRlc3RcDQoqKlJlc3VsdDogRmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyoqDQpgYGB7cn0NCiMgSW5pdGlhbCBDaGVjaw0Kc3VtbWFyeShhcy5udW1lcmljKHJhd2RhdGFfdmFsdWUkUTMuMTIpKQ0KDQpxM18xMl90YWJsZSA8LSByYXdkYXRhX3ZhbHVlWywgYygiUTMuMTIiLCAiZ3JvdXAiKV0NCnEzXzEyX2NvbnRpbmdlbmN5IDwtIHRhYmxlKHEzXzEyX3RhYmxlJFEzLjEyLCBxM18xMl90YWJsZSRncm91cCkNCnByaW50KHEzXzEyX2NvbnRpbmdlbmN5KQ0KIyBDaGktc3F1YXJlZCB0ZXN0DQpjaGlzcS50ZXN0KHEzXzEyX2NvbnRpbmdlbmN5KQ0KDQpgYGANCkZyZXF1ZW5jeSBvZiBDaGVja2luZyBDdXJyZW50IEluZmxhdGlvbiBwcm9wb3J0aW9uIGJhciBwbG90IGFjcm9zcyBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCnEzXzEyX3Byb3AgIDwtIGFzLmRhdGEuZnJhbWUocTNfMTJfY29udGluZ2VuY3kpDQojIHJlbmFtZSBjb2x1bW5zDQpuYW1lcyhxM18xMl9wcm9wKSA8LSBjKCJRMy4xMiIsICJHcm91cCIsICJDb3VudCIpDQoNCiMgYWRkIGEgbGFiZWxsZWQgY29sdW1uDQpxM18xMl9wcm9wIDwtIHEzXzEyX3Byb3AgJT4lDQogIG11dGF0ZShRMy4xMl9sYWJlbCA9IGNhc2Vfd2hlbigNCiAgICBRMy4xMiA9PSAiMSIgfiAiMS1OZXZlciIsDQogICAgUTMuMTIgPT0gIjIiIH4gIjItUmFyZWx5IiwNCiAgICBRMy4xMiA9PSAiMyIgfiAiMy1Tb21ldGltZXMiLA0KICAgIFEzLjEyID09ICI0IiB+ICI0LU9mdGVuIg0KICApKQ0KIyBjYWxjdWxhdGUgcHJvcG9ydGlvbnMgd2l0aGluIGVhY2ggZ3JvdXANCnEzXzEyX3Byb3AgPC0gcTNfMTJfcHJvcCAlPiUNCiAgZ3JvdXBfYnkoR3JvdXApICU+JQ0KICBtdXRhdGUoUHJvcG9ydGlvbiA9IENvdW50IC8gc3VtKENvdW50KSkNCg0KZ2dwbG90KHEzXzEyX3Byb3AsIGFlcyh4ID0gYXMuZmFjdG9yKGBRMy4xMl9sYWJlbGApLCB5ID0gUHJvcG9ydGlvbiwgZmlsbCA9IEdyb3VwKSkgKyBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJRMy4xMiBGcmVxdWVuY3kgb2YgQ2hlY2tpbmcgQ3VycmVudCBJbmZsYXRpb24gUHJvcG90aW9uIFBsb3QgYWNyb3NzIEdyb3VwcyIsDQogICAgeCA9ICJSZXNwb25zZSIsDQogICAgeSA9ICJQcm9wb3J0aW9uIg0KICApICsNCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCiAgDQpgYGANClBsb3QgcGllIGNoYXJ0IGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCnEzXzEyX3N1bW1hcnkgPC0gcTNfMTJfcHJvcCAlPiUNCiAgZ3JvdXBfYnkoYFEzLjEyX2xhYmVsYCkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9jb3VudCA9IHN1bShDb3VudCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IHRvdGFsX2NvdW50IC8gc3VtKHRvdGFsX2NvdW50KSwNCiAgICAgICAgIGBRMy4xMl9sYWJlbGAgPSBwYXN0ZTAoYFEzLjEyX2xhYmVsYCwgIiAoIiwgcm91bmQocHJvcG9ydGlvbiAqIDEwMCwgMiksICIgJSkiKSkNCmdncGxvdChxM18xMl9zdW1tYXJ5LCBhZXMoeCA9ICIiLHkgPSBwcm9wb3J0aW9uLCBmaWxsID0gYFEzLjEyX2xhYmVsYCkpICsNCiAgZ2VvbV9jb2wod2lkdGggPSAxKSArDQogIGNvb3JkX3BvbGFyKHRoZXRhID0gInkiKSArDQogIGxhYnModGl0bGUgPSAiUTMuMTIgRnJlcXVlbmN5IG9mIENoZWNraW5nIEN1cnJlbnQgSW5mbGF0aW9uIFN1bW1hcnkgUGllIENoYXJ0IiwNCiAgICAgICB4ID0gIiIsDQogICAgICAgeSA9ICIiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKQ0KYGBgDQoNCg0KIyMgUTMuMTMgU291cmNlIG9mIEN1cnJlbnQgSW5mbGF0aW9uDQpXaGljaCBzb3VyY2UgZG8geW91IHJlbHkgb24gdG8gaW5mb3JtIHlvdXJzZWxmIGFib3V0IHRoZSBjdXJyZW50IHZhbHVlIG9mIGluZmxhdGlvbj9cDQpWYXJpYWJsZTogY2F0ZWdvcmljYWxcDQpNZXRob2Q6IGNvbnZlcnQgdG8gbGlzdCBhbmQgY291bnQgKyBjaGktc3F1YXJlZCB0ZXN0XA0KKipSZXN1bHQ6IEZhaWwgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMqKg0KYGBge3J9DQpxM18xM190YWJsZSA8LSByYXdkYXRhX3ZhbHVlWywgYygiUTMuMTMiLCAiZ3JvdXAiKV0NCnEzXzEzX3RhYmxlJFEzLjEzIDwtIGxhcHBseShxM18xM190YWJsZSRRMy4xMywgZnVuY3Rpb24oeCkgYXMubGlzdChhcy5udW1lcmljKHN0cnNwbGl0KHgsICIsIilbWzFdXSkpKQ0KIyBjb3VudCB0aGUgbnVtYmVyIG9mIG9jY3VycmVuY2VzIG9mIGVhY2ggdmFsdWUNCnEzXzEzX3Byb3AgPC0gcTNfMTNfdGFibGUgJT4lDQogIHVubmVzdChRMy4xMykgJT4lDQogIGdyb3VwX2J5KGdyb3VwLGBRMy4xM2ApICU+JQ0KICBzdW1tYXJpc2UoY291bnQgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpDQpxM18xM19wcm9wJFEzLjEzIDwtIGFzLm51bWVyaWMocTNfMTNfcHJvcCRRMy4xMykNCiMgY3JlYXRlIGEgY29udGluZ2VuY3kgdGFibGUNCnEzXzEzX2NvbnRpbmdlbmN5IDwtIHh0YWJzKGNvdW50IH4gYFEzLjEzYCArIGdyb3VwLCBkYXRhID0gcTNfMTNfcHJvcCkNCnByaW50KHEzXzEzX2NvbnRpbmdlbmN5KQ0KIyBDaGktc3F1YXJlZCB0ZXN0DQpjaGlzcS50ZXN0KHEzXzEzX2NvbnRpbmdlbmN5KQ0KYGBgDQpQbG90IHNvdXJjZSBvZiBjdXJyZW50IGluZmxhdGlvbiBwcm9wb3J0aW9uIGJhciBwbG90IGFjcm9zcyBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCiMgY29udmVydCBjb250aW5nZW5jeSB0YWJsZSB0byBkYXRhIGZyYW1lDQpxM18xM19wcm9wIDwtIGFzLmRhdGEuZnJhbWUocTNfMTNfY29udGluZ2VuY3kpICU+JQ0KICBsZWZ0X2pvaW4oZ3JvdXBfdG90YWwsIGJ5ID0gImdyb3VwIikgJT4lDQogIG11dGF0ZShQcm9wb3J0aW9uID0gRnJlcSAvIG5fcmVzcG9uZGVudHMpDQoNCiMgYWRkIGEgbGFiZWxsZWQgY29sdW1uDQpxM18xM19wcm9wIDwtIHEzXzEzX3Byb3AgJT4lDQogIG11dGF0ZShRMy4xM19sYWJlbCA9IGNhc2Vfd2hlbigNCiAgICBgUTMuMTNgID09ICIxIiB+ICIxLVRlbGV2aXNpb24sIHJhZGlvIG9yIHByaW50IG1lZGlhIiwNCiAgICBgUTMuMTNgID09ICIyIiB+ICIyLVNvY2lhbCBtZWRpYSIsDQogICAgYFEzLjEzYCA9PSAiMyIgfiAiMy1PZmZpY2lhbCB3ZWJzaXRlcyBvciBkYXRhIHJlbGVhc2VzIiwNCiAgICBgUTMuMTNgID09ICI0IiB+ICI0LUNvbnRlbnQgcGxhdGZvcm0iLA0KICAgIGBRMy4xM2AgPT0gIjUiIH4gIjUtQWN0aXZlbHkgc2VhcmNoIG9uIHNlYXJjaCBlbmdpbmVzIiwNCiAgICBgUTMuMTNgID09ICI2IiB+ICI2LUZhbWlseSBvciBmcmllbmRzIiwNCiAgICBgUTMuMTNgID09ICI3IiB+ICI3LUZpbmFuY2lhbCBhZHZpY2Ugd2Vic2l0ZXMvZm9ydW1zIiwNCiAgICBgUTMuMTNgID09ICI4IiB+ICI4LVByaXZhdGUgYmFua3Mgb3IgZWNvbm9taWMgcmVzZWFyY2ggaW5zdGl0dXRlcyIsDQogICAgYFEzLjEzYCA9PSAiOSIgfiAiOS1PdGhlciINCiAgKSkNCmdncGxvdChxM18xM19wcm9wLCBhZXMoeCA9IGZhY3RvcihgUTMuMTNfbGFiZWxgKSwgeSA9IFByb3BvcnRpb24sIGZpbGwgPSBncm91cCkpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUTMuMTMgU291cmNlIG9mIEN1cnJlbnQgSW5mbGF0aW9uIFByb3BvdGlvbiBQbG90IGFjcm9zcyBHcm91cHMiLA0KICAgIHggPSAiUmVzcG9uc2UiLA0KICAgIHkgPSAiUHJvcG9ydGlvbiIsDQogICAgZmlsbCA9ICJHcm91cCINCiAgKSArDQogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KDQpgYGANClBsb3QgcGVyY2VudGFnZSBiYXIgY2hhcnQgaW5jbHVkaW5nIGFsbCBwYXJ0aWNpcGFudHMNCmBgYHtyfQ0KcTNfMTNfc3VtbWFyeSA8LSBxM18xM19wcm9wICU+JQ0KICBncm91cF9ieShgUTMuMTNfbGFiZWxgKSAlPiUNCiAgc3VtbWFyaXNlKHRvdGFsX2NvdW50ID0gc3VtKEZyZXEpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSB0b3RhbF9jb3VudCAvIHRvdGFsX3Jlc3BvbmRlbnRzKQ0KDQpnZ3Bsb3QocTNfMTNfc3VtbWFyeSwgYWVzKHggPSBmYWN0b3IoUTMuMTNfbGFiZWwpLCB5ID0gcHJvcG9ydGlvbikpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICJzdGVlbGJsdWUiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZTAocm91bmQocHJvcG9ydGlvbiAqIDEwMCwgMSksICIlIikpLCANCiAgICAgICAgICAgIHZqdXN0ID0gLTAuMywgc2l6ZSA9IDMuNSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUGVyY2VudGFnZSBvZiBQYXJ0aWNpcGFudHMgU2VsZWN0aW5nIEVhY2ggUTMuMTMgT3B0aW9uIiwNCiAgICB4ID0gIlJlc3BvbnNlIiwNCiAgICB5ID0gIlBlcmNlbnRhZ2Ugb2YgUGFydGljaXBhbnRzIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQojIyBRMy4xNCBJbXBhY3Qgb2YgQ3VycmVudCBJbmZsYXRpb24NClRvIHdoYXQgZXh0ZW50IGRvIHlvdSBmZWVsIHRoYXQgdGhlIGN1cnJlbnQgdmFsdWUgb2YgaW5mbGF0aW9uIGlzIGltcGFjdGluZyB5b3VyIHBlcnNvbmFsIGZpbmFuY2VzPw0KVmFyaWFibGU6IGNhdGVnb3JpY2FsXA0KTWV0aG9kOiBjb250aW5nZW5jeSB0YWJsZSArIGNoaS1zcXVhcmVkIHRlc3RcDQoqKlJlc3VsdDogRmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyoqDQpgYGB7cn0NCiMgSW5pdGlhbCBDaGVjaw0Kc3VtbWFyeShhcy5udW1lcmljKHJhd2RhdGFfdmFsdWUkUTMuMTQpKQ0KcTNfMTRfdGFibGUgPC0gcmF3ZGF0YV92YWx1ZVssIGMoIlEzLjE0IiwgImdyb3VwIildDQpxM18xNF9jb250aW5nZW5jeSA8LSB0YWJsZShxM18xNF90YWJsZSRRMy4xNCwgcTNfMTRfdGFibGUkZ3JvdXApDQpwcmludChxM18xNF9jb250aW5nZW5jeSkNCiMgQ2hpLXNxdWFyZWQgdGVzdA0KY2hpc3EudGVzdChxM18xNF9jb250aW5nZW5jeSkNCg0KYGBgDQpJbXBhY3Qgb2YgQ3VycmVudCBJbmZsYXRpb24gcHJvcG9ydGlvbiBiYXIgcGxvdCBhY3Jvc3MgZGlmZmVyZW50IGdyb3Vwcw0KYGBge3J9DQpxM18xNF9wcm9wICA8LSBhcy5kYXRhLmZyYW1lKHEzXzE0X2NvbnRpbmdlbmN5KQ0KIyByZW5hbWUgY29sdW1ucw0KbmFtZXMocTNfMTRfcHJvcCkgPC0gYygiUTMuMTQiLCAiR3JvdXAiLCAiQ291bnQiKQ0KIyBhZGQgYSBsYWJlbGxlZCBjb2x1bW4NCnEzXzE0X3Byb3AgPC0gcTNfMTRfcHJvcCAlPiUNCiAgbXV0YXRlKFEzLjE0X2xhYmVsID0gY2FzZV93aGVuKA0KICAgIFEzLjE0ID09ICIxIiB+ICIxLU5vdCBhdCBhbGwiLA0KICAgIFEzLjE0ID09ICIyIiB+ICIyLVNsaWdodGx5IiwNCiAgICBRMy4xNCA9PSAiMyIgfiAiMy1Nb2RlcmF0ZWx5IiwNCiAgICBRMy4xNCA9PSAiNCIgfiAiNC1WZXJ5IHNpZ25pZmljYW50bHkiDQogICkpDQojIGNhbGN1bGF0ZSBwcm9wb3J0aW9ucyB3aXRoaW4gZWFjaCBncm91cA0KcTNfMTRfcHJvcCA8LSBxM18xNF9wcm9wICU+JQ0KICBncm91cF9ieShHcm91cCkgJT4lDQogIG11dGF0ZShQcm9wb3J0aW9uID0gQ291bnQgLyBzdW0oQ291bnQpKQ0KZ2dwbG90KHEzXzE0X3Byb3AsIGFlcyh4ID0gYXMuZmFjdG9yKGBRMy4xNF9sYWJlbGApLCB5ID0gUHJvcG9ydGlvbiwgZmlsbCA9IEdyb3VwKSkgKyBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJRMy4xNCBJbXBhY3Qgb2YgQ3VycmVudCBJbmZsYXRpb24gUHJvcG90aW9uIFBsb3QgYWNyb3NzIEdyb3VwcyIsDQogICAgeCA9ICJSZXNwb25zZSIsDQogICAgeSA9ICJQcm9wb3J0aW9uIg0KICApICsNCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KYGBgDQpQbG90IHBpZSBjaGFydCBpbmNsdWRpbmcgYWxsIHBhcnRpY2lwYW50cw0KYGBge3J9DQpxM18xNF9zdW1tYXJ5IDwtIHEzXzE0X3Byb3AgJT4lDQogIGdyb3VwX2J5KGBRMy4xNF9sYWJlbGApICU+JQ0KICBzdW1tYXJpc2UodG90YWxfY291bnQgPSBzdW0oQ291bnQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSB0b3RhbF9jb3VudCAvIHN1bSh0b3RhbF9jb3VudCksDQogICAgICAgIGBRMy4xNF9sYWJlbGAgPSBwYXN0ZTAoYFEzLjE0X2xhYmVsYCwgIiAoIiwgcm91bmQocHJvcG9ydGlvbiAqIDEwMCwgMiksICIgJSkiKSkNCmdncGxvdChxM18xNF9zdW1tYXJ5LCBhZXMoeCA9ICIiLHkgPSBwcm9wb3J0aW9uLCBmaWxsID0gYFEzLjE0X2xhYmVsYCkpICsNCiAgZ2VvbV9jb2wod2lkdGggPSAxKSArDQogIGNvb3JkX3BvbGFyKHRoZXRhID0gInkiKSArDQogIGxhYnModGl0bGUgPSAiUTMuMTQgSW1wYWN0IG9mIEN1cnJlbnQgSW5mbGF0aW9uIFN1bW1hcnkgUGllIENoYXJ0IiwNCiAgICAgICB4ID0gIiIsDQogICAgICAgeSA9ICIiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKQ0KYGBgDQoNCiMjIFEzLjE1IFJlc3BvbnNlIHRvIEN1cnJlbnQgSW5mbGF0aW9uDQpIb3cgbXVjaCBkbyB5b3UgYWRqdXN0IG9yIHRha2UgYWN0aW9uIGluIHJlc3BvbnNlIHRvIHRoZSBjaGFuZ2UgaW4gY3VycmVudCB2YWx1ZSBvZiBpbmZsYXRpb24/XA0KVmFyaWFibGU6IGNhdGVnb3JpY2FsXA0KTWV0aG9kOiBjb250aW5nZW5jeSB0YWJsZSArIGNoaS1zcXVhcmVkIHRlc3RcDQoqKlJlc3VsdDogRmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyoqDQpgYGB7cn0NCiMgSW5pdGlhbCBDaGVjaw0Kc3VtbWFyeShhcy5udW1lcmljKHJhd2RhdGFfdmFsdWUkUTMuMTUpKQ0KcTNfMTVfdGFibGUgPC0gcmF3ZGF0YV92YWx1ZVssIGMoIlEzLjE1IiwgImdyb3VwIildDQpxM18xNV9jb250aW5nZW5jeSA8LSB0YWJsZShxM18xNV90YWJsZSRRMy4xNSwgcTNfMTVfdGFibGUkZ3JvdXApDQpwcmludChxM18xNV9jb250aW5nZW5jeSkNCiMgQ2hpLXNxdWFyZWQgdGVzdA0KY2hpc3EudGVzdChxM18xNV9jb250aW5nZW5jeSkNCg0KYGBgDQpSZXNwb25zZSB0byBDdXJyZW50IEluZmxhdGlvbiBwcm9wb3J0aW9uIGJhciBwbG90IGFjcm9zcyBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCnEzXzE1X3Byb3AgIDwtIGFzLmRhdGEuZnJhbWUocTNfMTVfY29udGluZ2VuY3kpDQojIHJlbmFtZSBjb2x1bW5zDQpuYW1lcyhxM18xNV9wcm9wKSA8LSBjKCJRMy4xNSIsICJHcm91cCIsICJDb3VudCIpDQojIGFkZCBhIGxhYmVsbGVkIGNvbHVtbg0KcTNfMTVfcHJvcCA8LSBxM18xNV9wcm9wICU+JQ0KICBtdXRhdGUoUTMuMTVfbGFiZWwgPSBjYXNlX3doZW4oDQogICAgUTMuMTUgPT0gIjEiIH4gIjEtTm90IGF0IGFsbCIsDQogICAgUTMuMTUgPT0gIjIiIH4gIjItUmFyZWx5IiwNCiAgICBRMy4xNSA9PSAiMyIgfiAiMy1Tb21ld2hhdCBhY3RpdmVseSIsDQogICAgUTMuMTUgPT0gIjQiIH4gIjQtVmVyeSBhY3RpdmVseSINCiAgKSkNCiMgY2FsY3VsYXRlIHByb3BvcnRpb25zIHdpdGhpbiBlYWNoIGdyb3VwDQpxM18xNV9wcm9wIDwtIHEzXzE1X3Byb3AgJT4lDQogIGdyb3VwX2J5KEdyb3VwKSAlPiUNCiAgbXV0YXRlKFByb3BvcnRpb24gPSBDb3VudCAvIHN1bShDb3VudCkpDQpnZ3Bsb3QocTNfMTVfcHJvcCwgYWVzKHggPSBhcy5mYWN0b3IoYFEzLjE1X2xhYmVsYCksIHkgPSBQcm9wb3J0aW9uLCBmaWxsID0gR3JvdXApKSArIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlEzLjE1IFJlc3BvbnNlIHRvIEN1cnJlbnQgSW5mbGF0aW9uIFByb3BvdGlvbiBQbG90IGFjcm9zcyBHcm91cHMiLA0KICAgIHggPSAiUmVzcG9uc2UiLA0KICAgIHkgPSAiUHJvcG9ydGlvbiINCiAgKSArDQogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANClBsb3QgcGllIGNoYXJ0IGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCnEzXzE1X3N1bW1hcnkgPC0gcTNfMTVfcHJvcCAlPiUNCiAgZ3JvdXBfYnkoYFEzLjE1X2xhYmVsYCkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9jb3VudCA9IHN1bShDb3VudCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IHRvdGFsX2NvdW50IC8gc3VtKHRvdGFsX2NvdW50KSwNCiAgICAgICAgIGBRMy4xNV9ncmFwaF9sYWJlbGAgPSBwYXN0ZTAoYFEzLjE1X2xhYmVsYCwgIiAoIiwgcm91bmQocHJvcG9ydGlvbiAqIDEwMCwgMiksICIgJSkiKSkNCmdncGxvdChxM18xNV9zdW1tYXJ5LCBhZXMoeCA9ICIiLHkgPSBwcm9wb3J0aW9uLCBmaWxsID0gYFEzLjE1X2dyYXBoX2xhYmVsYCkpICsNCiAgZ2VvbV9jb2wod2lkdGggPSAxKSArDQogIGNvb3JkX3BvbGFyKHRoZXRhID0gInkiKSArDQogIGxhYnModGl0bGUgPSAiUTMuMTUgUmVzcG9uc2UgdG8gQ3VycmVudCBJbmZsYXRpb24gU3VtbWFyeSBQaWUgQ2hhcnQiLA0KICAgICAgIHggPSAiIiwNCiAgICAgICB5ID0gIiIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpDQoNCmBgYA0KDQojIyBRMy4xNiBGcmVxdWVuY3kgb2YgQ2hlY2tpbmcgSW5mbGF0aW9uIEZvcmVjYXN0cw0KSG93IG9mdGVuIGRvIHlvdSBsb29rIGF0IGluZmxhdGlvbiBmb3JlY2FzdHMgKHRoYXQgaXMsIGluZm9ybWF0aW9uIGFib3V0IGZ1dHVyZSBpbmZsYXRpb24pP1wNClZhcmlhYmxlOiBjYXRlZ29yaWNhbFwNCk1ldGhvZDogY29udGluZ2VuY3kgdGFibGUgKyBjaGktc3F1YXJlZCB0ZXN0XA0KKipSZXN1bHQ6IEZhaWwgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMqKg0KYGBge3J9DQojIEluaXRpYWwgQ2hlY2sNCnN1bW1hcnkoYXMubnVtZXJpYyhyYXdkYXRhX3ZhbHVlJFEzLjE2KSkNCg0KcTNfMTZfdGFibGUgPC0gcmF3ZGF0YV92YWx1ZVssIGMoIlEzLjE2IiwgImdyb3VwIildDQpxM18xNl9jb250aW5nZW5jeSA8LSB0YWJsZShxM18xNl90YWJsZSRRMy4xNiwgcTNfMTZfdGFibGUkZ3JvdXApDQpwcmludChxM18xNl9jb250aW5nZW5jeSkNCiMgQ2hpLXNxdWFyZWQgdGVzdA0KY2hpc3EudGVzdChxM18xNl9jb250aW5nZW5jeSkNCg0KYGBgDQpGcmVxdWVuY3kgb2YgQ2hlY2tpbmcgSW5mbGF0aW9uIEZvcmVjYXN0cyBwcm9wb3J0aW9uIGJhciBwbG90IGFjcm9zcyBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCnEzXzE2X3Byb3AgIDwtIGFzLmRhdGEuZnJhbWUocTNfMTZfY29udGluZ2VuY3kpDQojIHJlbmFtZSBjb2x1bW5zDQpuYW1lcyhxM18xNl9wcm9wKSA8LSBjKCJRMy4xNiIsICJHcm91cCIsICJDb3VudCIpDQojIGFkZCBhIGxhYmVsbGVkIGNvbHVtbg0KcTNfMTZfcHJvcCA8LSBxM18xNl9wcm9wICU+JQ0KICBtdXRhdGUoUTMuMTZfbGFiZWwgPSBjYXNlX3doZW4oDQogICAgUTMuMTYgPT0gIjEiIH4gIjEtTmV2ZXIiLA0KICAgIFEzLjE2ID09ICIyIiB+ICIyLVJhcmVseSIsDQogICAgUTMuMTYgPT0gIjMiIH4gIjMtU29tZXRpbWVzIiwNCiAgICBRMy4xNiA9PSAiNCIgfiAiNC1PZnRlbiINCiAgKSkNCiMgY2FsY3VsYXRlIHByb3BvcnRpb25zIHdpdGhpbiBlYWNoIGdyb3VwDQpxM18xNl9wcm9wIDwtIHEzXzE2X3Byb3AgJT4lDQogIGdyb3VwX2J5KEdyb3VwKSAlPiUNCiAgbXV0YXRlKFByb3BvcnRpb24gPSBDb3VudCAvIHN1bShDb3VudCkpDQpnZ3Bsb3QocTNfMTZfcHJvcCwgYWVzKHggPSBhcy5mYWN0b3IoYFEzLjE2X2xhYmVsYCksIHkgPSBQcm9wb3J0aW9uLCBmaWxsID0gR3JvdXApKSArIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlEzLjE2IEZyZXF1ZW5jeSBvZiBDaGVja2luZyBJbmZsYXRpb24gRm9yZWNhc3RzIFByb3BvdGlvbiBQbG90IGFjcm9zcyBHcm91cHMiLA0KICAgIHggPSAiUmVzcG9uc2UiLA0KICAgIHkgPSAiUHJvcG9ydGlvbiINCiAgKSArDQogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANClBsb3QgcGllIGNoYXJ0IGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCnEzXzE2X3N1bW1hcnkgPC0gcTNfMTZfcHJvcCAlPiUNCiAgZ3JvdXBfYnkoYFEzLjE2X2xhYmVsYCkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9jb3VudCA9IHN1bShDb3VudCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IHRvdGFsX2NvdW50IC8gc3VtKHRvdGFsX2NvdW50KSwNCiAgICAgICAgIGBRMy4xNl9sYWJlbGAgPSBwYXN0ZTAoYFEzLjE2X2xhYmVsYCwgIiAoIiwgcm91bmQocHJvcG9ydGlvbiAqIDEwMCwgMiksICIgJSkiKSkNCmdncGxvdChxM18xNl9zdW1tYXJ5LCBhZXMoeCA9ICIiLHkgPSBwcm9wb3J0aW9uLCBmaWxsID0gYFEzLjE2X2xhYmVsYCkpICsNCiAgZ2VvbV9jb2wod2lkdGggPSAxKSArDQogIGNvb3JkX3BvbGFyKHRoZXRhID0gInkiKSArDQogIGxhYnModGl0bGUgPSAiUTMuMTYgRnJlcXVlbmN5IG9mIENoZWNraW5nIEluZmxhdGlvbiBGb3JlY2FzdHMgU3VtbWFyeSBQaWUgQ2hhcnQiLA0KICAgICAgIHggPSAiIiwNCiAgICAgICB5ID0gIiIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpDQpgYGANCg0KIyMgUTMuMTcgU291cmNlIG9mIEluZmxhdGlvbiBGb3JlY2FzdHMNCldoaWNoIHNvdXJjZSBkbyB5b3UgcmVseSBvbiB0byBvYnRhaW4gaW5mbGF0aW9uIGZvcmVjYXN0cyAoaW5mb3JtYXRpb24gYWJvdXQgZnV0dXJlIGluZmxhdGlvbik/XA0KVmFyaWFibGU6IGNhdGVnb3JpY2FsXA0KTWV0aG9kOiBjb252ZXJ0IHRvIGxpc3QgYW5kIGNvdW50ICsgY2hpLXNxdWFyZWQgdGVzdFwNCioqUmVzdWx0OiBGYWlsIHRvIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzKioNCmBgYHtyfQ0KcTNfMTdfdGFibGUgPC0gcmF3ZGF0YV92YWx1ZVssIGMoIlEzLjE3IiwgImdyb3VwIildDQpxM18xN190YWJsZSRRMy4xNyA8LSBsYXBwbHkocTNfMTdfdGFibGUkUTMuMTcsIGZ1bmN0aW9uKHgpIGFzLmxpc3QoYXMubnVtZXJpYyhzdHJzcGxpdCh4LCAiLCIpW1sxXV0pKSkNCiMgY291bnQgdGhlIG51bWJlciBvZiBvY2N1cnJlbmNlcyBvZiBlYWNoIHZhbHVlDQpxM18xN19wcm9wIDwtIHEzXzE3X3RhYmxlICU+JQ0KICB1bm5lc3QoUTMuMTcpICU+JQ0KICBncm91cF9ieShncm91cCxgUTMuMTdgKSAlPiUNCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCAuZ3JvdXBzID0gJ2Ryb3AnKQ0KcTNfMTdfcHJvcCRRMy4xNyA8LSBhcy5udW1lcmljKHEzXzE3X3Byb3AkUTMuMTcpDQojIGNyZWF0ZSBhIGNvbnRpbmdlbmN5IHRhYmxlDQpxM18xN19jb250aW5nZW5jeSA8LSB4dGFicyhjb3VudCB+IGBRMy4xN2AgKyBncm91cCwgZGF0YSA9IHEzXzE3X3Byb3ApDQpwcmludChxM18xN19jb250aW5nZW5jeSkNCiMgQ2hpLXNxdWFyZWQgdGVzdA0KY2hpc3EudGVzdChxM18xN19jb250aW5nZW5jeSkNCmBgYA0KUGxvdCBzb3VyY2Ugb2YgaW5mbGF0aW9uIGZvcmVjYXN0cyBwcm9wb3J0aW9uIGJhciBwbG90IGFjcm9zcyBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCiMgY29udmVydCBjb250aW5nZW5jeSB0YWJsZSB0byBkYXRhIGZyYW1lDQpxM18xN19wcm9wIDwtIGFzLmRhdGEuZnJhbWUocTNfMTdfY29udGluZ2VuY3kpICU+JQ0KICBsZWZ0X2pvaW4oZ3JvdXBfdG90YWwsIGJ5ID0gImdyb3VwIikgJT4lDQogIG11dGF0ZShQcm9wb3J0aW9uID0gRnJlcSAvIG5fcmVzcG9uZGVudHMpDQojIGFkZCBhIGxhYmVsbGVkIGNvbHVtbg0KcTNfMTdfcHJvcCA8LSBxM18xN19wcm9wICU+JQ0KICBtdXRhdGUoUTMuMTdfbGFiZWwgPSBjYXNlX3doZW4oDQogICAgYFEzLjE3YCA9PSAiMSIgfiAiMS1UZWxldmlzaW9uLCByYWRpbyBvciBwcmludCBtZWRpYSIsDQogICAgYFEzLjE3YCA9PSAiMiIgfiAiMi1Tb2NpYWwgbWVkaWEiLA0KICAgIGBRMy4xN2AgPT0gIjMiIH4gIjMtT2ZmaWNpYWwgd2Vic2l0ZXMgb3IgZGF0YSByZWxlYXNlcyIsDQogICAgYFEzLjE3YCA9PSAiNCIgfiAiNC1Db250ZW50IHBsYXRmb3JtIiwNCiAgICBgUTMuMTdgID09ICI1IiB+ICI1LUFjdGl2ZWx5IHNlYXJjaCBvbiBzZWFyY2ggZW5naW5lcyIsDQogICAgYFEzLjE3YCA9PSAiNiIgfiAiNi1GYW1pbHkgb3IgZnJpZW5kcyIsDQogICAgYFEzLjE3YCA9PSAiNyIgfiAiNy1GaW5hbmNpYWwgYWR2aWNlIHdlYnNpdGVzL2ZvcnVtcyIsDQogICAgYFEzLjE3YCA9PSAiOCIgfiAiOC1Qcml2YXRlIGJhbmtzIG9yIGVjb25vbWljIHJlc2VhcmNoIGluc3RpdHV0ZXMiLA0KICAgIGBRMy4xN2AgPT0gIjkiIH4gIjktT3RoZXIiDQogICkpDQpnZ3Bsb3QocTNfMTdfcHJvcCwgYWVzKHggPSBmYWN0b3IoYFEzLjE3X2xhYmVsYCksIHkgPSBQcm9wb3J0aW9uLCBmaWxsID0gZ3JvdXApKSArDQogIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlEzLjE3IFNvdXJjZSBvZiBJbmZsYXRpb24gRm9yZWNhc3RzIFByb3BvdGlvbiBQbG90IGFjcm9zcyBHcm91cHMiLA0KICAgIHggPSAiUmVzcG9uc2UiLA0KICAgIHkgPSAiUHJvcG9ydGlvbiIsDQogICAgZmlsbCA9ICJHcm91cCINCiAgKSArDQogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQpQbG90IHBlcmNlbnRhZ2UgYmFyIGNoYXJ0IGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCnEzXzE3X3N1bW1hcnkgPC0gcTNfMTdfcHJvcCAlPiUNCiAgZ3JvdXBfYnkoYFEzLjE3X2xhYmVsYCkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9jb3VudCA9IHN1bShGcmVxKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIG11dGF0ZShwcm9wb3J0aW9uID0gdG90YWxfY291bnQgLyB0b3RhbF9yZXNwb25kZW50cykNCmdncGxvdChxM18xN19zdW1tYXJ5LCBhZXMoeCA9IGZhY3RvcihRMy4xN19sYWJlbCksIHkgPSBwcm9wb3J0aW9uKSkgKw0KICBnZW9tX2NvbChmaWxsID0gInN0ZWVsYmx1ZSIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChyb3VuZChwcm9wb3J0aW9uICogMTAwLCAxKSwgIiUiKSksIA0KICAgICAgICAgICAgdmp1c3QgPSAtMC4zLCBzaXplID0gMy41KSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJQZXJjZW50YWdlIG9mIFBhcnRpY2lwYW50cyBTZWxlY3RpbmcgRWFjaCBRMy4xNyBPcHRpb24iLA0KICAgIHggPSAiUmVzcG9uc2UiLA0KICAgIHkgPSAiUGVyY2VudGFnZSBvZiBQYXJ0aWNpcGFudHMiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQoNCiMjIFEzLjE4IEltcGFjdCBvZiBJbmZsYXRpb24gRm9yZWNhc3RzDQpUbyB3aGF0IGV4dGVudCBkbyB5b3UgZmVlbCB0aGF0IGluZmxhdGlvbiBmb3JlY2FzdHMgKGluZm9ybWF0aW9uIGFib3V0IGZ1dHVyZSBpbmZsYXRpb24pIGltcGFjdCB5b3VyIHBlcnNvbmFsIGZpbmFuY2VzP1wNClZhcmlhYmxlOiBjYXRlZ29yaWNhbFwNCk1ldGhvZDogY29udGluZ2VuY3kgdGFibGUgKyBjaGktc3F1YXJlZCB0ZXN0XA0KKipSZXN1bHQ6IEZhaWwgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMqKg0KYGBge3J9DQojIEluaXRpYWwgQ2hlY2sNCnN1bW1hcnkoYXMubnVtZXJpYyhyYXdkYXRhX3ZhbHVlJFEzLjE4KSkNCnEzXzE4X3RhYmxlIDwtIHJhd2RhdGFfdmFsdWVbLCBjKCJRMy4xOCIsICJncm91cCIpXQ0KcTNfMThfY29udGluZ2VuY3kgPC0gdGFibGUocTNfMThfdGFibGUkUTMuMTgsIHEzXzE4X3RhYmxlJGdyb3VwKQ0KcHJpbnQocTNfMThfY29udGluZ2VuY3kpDQojIENoaS1zcXVhcmVkIHRlc3QNCmNoaXNxLnRlc3QocTNfMThfY29udGluZ2VuY3kpDQpgYGANCkltcGFjdCBvZiBJbmZsYXRpb24gRm9yZWNhc3RzIHByb3BvcnRpb24gYmFyIHBsb3QgYWNyb3NzIGRpZmZlcmVudCBncm91cHMNCmBgYHtyfQ0KcTNfMThfcHJvcCAgPC0gYXMuZGF0YS5mcmFtZShxM18xOF9jb250aW5nZW5jeSkNCiMgcmVuYW1lIGNvbHVtbnMNCm5hbWVzKHEzXzE4X3Byb3ApIDwtIGMoIlEzLjE4IiwgIkdyb3VwIiwgIkNvdW50IikNCiMgYWRkIGEgbGFiZWxsZWQgY29sdW1uDQpxM18xOF9wcm9wIDwtIHEzXzE4X3Byb3AgJT4lDQogIG11dGF0ZShRMy4xOF9sYWJlbCA9IGNhc2Vfd2hlbigNCiAgICBRMy4xOCA9PSAiMSIgfiAiMS1Ob3QgYXQgYWxsIiwNCiAgICBRMy4xOCA9PSAiMiIgfiAiMi1TbGlnaHRseSIsDQogICAgUTMuMTggPT0gIjMiIH4gIjMtTW9kZXJhdGVseSIsDQogICAgUTMuMTggPT0gIjQiIH4gIjQtVmVyeSBzaWduaWZpY2FudGx5Ig0KICApKQ0KIyBjYWxjdWxhdGUgcHJvcG9ydGlvbnMgd2l0aGluIGVhY2ggZ3JvdXANCnEzXzE4X3Byb3AgPC0gcTNfMThfcHJvcCAlPiUNCiAgZ3JvdXBfYnkoR3JvdXApICU+JQ0KICBtdXRhdGUoUHJvcG9ydGlvbiA9IENvdW50IC8gc3VtKENvdW50KSkNCmdncGxvdChxM18xOF9wcm9wLCBhZXMoeCA9IGFzLmZhY3RvcihgUTMuMThfbGFiZWxgKSwgeSA9IFByb3BvcnRpb24sIGZpbGwgPSBHcm91cCkpICsgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUTMuMTggSW1wYWN0IG9mIEluZmxhdGlvbiBGb3JlY2FzdHMgUHJvcG90aW9uIFBsb3QgYWNyb3NzIEdyb3VwcyIsDQogICAgeCA9ICJSZXNwb25zZSIsDQogICAgeSA9ICJQcm9wb3J0aW9uIg0KICApICsNCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KYGBgDQpQbG90IHBpZSBjaGFydCBpbmNsdWRpbmcgYWxsIHBhcnRpY2lwYW50cw0KYGBge3J9DQpxM18xOF9zdW1tYXJ5IDwtIHEzXzE4X3Byb3AgJT4lDQogIGdyb3VwX2J5KGBRMy4xOF9sYWJlbGApICU+JQ0KICBzdW1tYXJpc2UodG90YWxfY291bnQgPSBzdW0oQ291bnQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSB0b3RhbF9jb3VudCAvIHN1bSh0b3RhbF9jb3VudCksDQogICAgICAgICBgUTMuMThfbGFiZWxgID0gcGFzdGUwKGBRMy4xOF9sYWJlbGAsICIgKCIsIHJvdW5kKHByb3BvcnRpb24gKiAxMDAsIDIpLCAiICUpIikpDQpnZ3Bsb3QocTNfMThfc3VtbWFyeSwgYWVzKHggPSAiIix5ID0gcHJvcG9ydGlvbiwgZmlsbCA9IGBRMy4xOF9sYWJlbGApKSArDQogIGdlb21fY29sKHdpZHRoID0gMSkgKw0KICBjb29yZF9wb2xhcih0aGV0YSA9ICJ5IikgKw0KICBsYWJzKHRpdGxlID0gIlEzLjE4IEltcGFjdCBvZiBJbmZsYXRpb24gRm9yZWNhc3RzIFN1bW1hcnkgUGllIENoYXJ0IiwNCiAgICAgICB4ID0gIiIsDQogICAgICAgeSA9ICIiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKQ0KYGBgDQoNCiMjIFEzLjE5IFJlc3BvbnNlIHRvIEluZmxhdGlvbiBGb3JlY2FzdHMNCkhvdyBtdWNoIGRvIHlvdSBhZGp1c3Qgb3IgdGFrZSBhY3Rpb24gaW4gcmVzcG9uc2UgdG8gaW5mbGF0aW9uIGZvcmVjYXN0cyAoaW5mb3JtYXRpb24gYWJvdXQgZnV0dXJlIGluZmxhdGlvbik/XA0KVmFyaWFibGU6IGNhdGVnb3JpY2FsXA0KTWV0aG9kOiBjb250aW5nZW5jeSB0YWJsZSArIGNoaS1zcXVhcmVkIHRlc3RcDQoqKlJlc3VsdDogRmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyoqDQpgYGB7cn0NCiMgSW5pdGlhbCBDaGVjaw0Kc3VtbWFyeShhcy5udW1lcmljKHJhd2RhdGFfdmFsdWUkUTMuMTkpKQ0KcTNfMTlfdGFibGUgPC0gcmF3ZGF0YV92YWx1ZVssIGMoIlEzLjE5IiwgImdyb3VwIildDQpxM18xOV9jb250aW5nZW5jeSA8LSB0YWJsZShxM18xOV90YWJsZSRRMy4xOSwgcTNfMTlfdGFibGUkZ3JvdXApDQpwcmludChxM18xOV9jb250aW5nZW5jeSkNCiMgQ2hpLXNxdWFyZWQgdGVzdA0KY2hpc3EudGVzdChxM18xOV9jb250aW5nZW5jeSkNCmBgYA0KUmVzcG9uc2UgdG8gSW5mbGF0aW9uIEZvcmVjYXN0cyBwcm9wb3J0aW9uIGJhciBwbG90IGFjcm9zcyBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCnEzXzE5X3Byb3AgIDwtIGFzLmRhdGEuZnJhbWUocTNfMTlfY29udGluZ2VuY3kpDQojIHJlbmFtZSBjb2x1bW5zDQpuYW1lcyhxM18xOV9wcm9wKSA8LSBjKCJRMy4xOSIsICJHcm91cCIsICJDb3VudCIpDQojIGFkZCBhIGxhYmVsbGVkIGNvbHVtbg0KcTNfMTlfcHJvcCA8LSBxM18xOV9wcm9wICU+JQ0KICBtdXRhdGUoUTMuMTlfbGFiZWwgPSBjYXNlX3doZW4oDQogICAgUTMuMTkgPT0gIjEiIH4gIjEtTm90IGF0IGFsbCIsDQogICAgUTMuMTkgPT0gIjIiIH4gIjItUmFyZWx5IiwNCiAgICBRMy4xOSA9PSAiMyIgfiAiMy1Tb21ld2hhdCBhY3RpdmVseSIsDQogICAgUTMuMTkgPT0gIjQiIH4gIjQtVmVyeSBhY3RpdmVseSINCiAgKSkNCiMgY2FsY3VsYXRlIHByb3BvcnRpb25zIHdpdGhpbiBlYWNoIGdyb3VwDQpxM18xOV9wcm9wIDwtIHEzXzE5X3Byb3AgJT4lDQogIGdyb3VwX2J5KEdyb3VwKSAlPiUNCiAgbXV0YXRlKFByb3BvcnRpb24gPSBDb3VudCAvIHN1bShDb3VudCkpDQpnZ3Bsb3QocTNfMTlfcHJvcCwgYWVzKHggPSBhcy5mYWN0b3IoYFEzLjE5X2xhYmVsYCksIHkgPSBQcm9wb3J0aW9uLCBmaWxsID0gR3JvdXApKSArIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlEzLjE5IFJlc3BvbnNlIHRvIEluZmxhdGlvbiBGb3JlY2FzdHMgUHJvcG90aW9uIFBsb3QgYWNyb3NzIEdyb3VwcyIsDQogICAgeCA9ICJSZXNwb25zZSIsDQogICAgeSA9ICJQcm9wb3J0aW9uIg0KICApICsNCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KUGxvdCBwaWUgY2hhcnQgaW5jbHVkaW5nIGFsbCBwYXJ0aWNpcGFudHMNCmBgYHtyfQ0KcTNfMTlfc3VtbWFyeSA8LSBxM18xOV9wcm9wICU+JQ0KICBncm91cF9ieShgUTMuMTlfbGFiZWxgKSAlPiUNCiAgc3VtbWFyaXNlKHRvdGFsX2NvdW50ID0gc3VtKENvdW50KSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lDQogIG11dGF0ZShwcm9wb3J0aW9uID0gdG90YWxfY291bnQgLyBzdW0odG90YWxfY291bnQpLA0KICAgICAgICAgYFEzLjE5X2dyYXBoX2xhYmVsYCA9IHBhc3RlMChgUTMuMTlfbGFiZWxgLCAiICgiLCByb3VuZChwcm9wb3J0aW9uICogMTAwLCAyKSwgIiAlKSIpKQ0KZ2dwbG90KHEzXzE5X3N1bW1hcnksIGFlcyh4ID0gIiIseSA9IHByb3BvcnRpb24sIGZpbGwgPSBgUTMuMTlfZ3JhcGhfbGFiZWxgKSkgKw0KICBnZW9tX2NvbCh3aWR0aCA9IDEpICsNCiAgY29vcmRfcG9sYXIodGhldGEgPSAieSIpICsNCiAgbGFicyh0aXRsZSA9ICJRMy4xOSBSZXNwb25zZSB0byBJbmZsYXRpb24gRm9yZWNhc3RzIFN1bW1hcnkgUGllIENoYXJ0IiwNCiAgICAgICB4ID0gIiIsDQogICAgICAgeSA9ICIiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKQ0KYGBgDQoNCg0KDQoNCiMgQWN0dWFsIFN1cnZleSBBbmFseXNpcyA8YSBuYW1lPSJhY3R1YWwtc3VydmV5LWFuYWx5c2lzIj48L2E+DQoNCiMjICEgUXh4LjIgR3JhcGggRmFtaWxhcml0eQ0KSGF2ZSB5b3UgZXZlciBiZWVuIGNvbW11bmljYXRlZCB0aGlzIHR5cGUgb2YgaW5mb3JtYXRpb24gYmVmb3JlP1wNClZhcmlhYmxlOiBjYXRlZ29yaWNhbFwNCk1ldGhvZDogQ29udGluZ2VuY3kgVGFibGUgKyBDaGktc3F1YXJlZCB0ZXN0XA0KKnJlY29kZSB0byB5ZXMgYW5kIG5vKlwNCioqUmVzdWx0OiBXZSBjYW4gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMsIG1lYW5pbmcgcGVvcGxlIGFyZSBtb3JlIG9yIGxlc3MgZmFtaWxpYXIgd2l0aCBjZXJ0YWluIHR5cGUgb2YgdmlzdWFsaXNhdGlvbnMuKioNCmBgYHtyfQ0KIyBjb21iaW5lIGRhdGEgZnJvbSBkaWZmZXJlbnQgZ3JvdXBzDQpzdXJ2ZXlfcTIgPC0gZGF0YS5mcmFtZSgpDQpzdXJ2ZXlfcTJfbGlzdCA8LSBsaXN0KCJRNC4yIiwiUTYuMiIsICJROC4yIiwgIlExMC4yIiwgIlExMi4yIikNCg0KZm9yIChpIGluIHNlcV9hbG9uZyhncm91cF9saXN0KSkgew0KICBkZiA8LSBncm91cF9saXN0W1tpXV0NCiAgY29sIDwtIHN1cnZleV9xMl9saXN0W1tpXV0NCiAgdGVtcF90YWJsZSA8LSBkZlssIGMoY29sLCAiZ3JvdXAiKV0NCiAgbmFtZXModGVtcF90YWJsZSkgPC0gYygicTJfdmFsdWUiLCAiZ3JvdXAiKQ0KICBzdXJ2ZXlfcTIgPC0gcmJpbmQoc3VydmV5X3EyLCB0ZW1wX3RhYmxlKQ0KfQ0KDQojIHJlY29kZSB0aGUgY2F0ZWdvcnkNCnN1cnZleV9xMiA8LSBzdXJ2ZXlfcTIgJT4lDQogIG11dGF0ZShxMl9yZWNvZGUgPSBjYXNlX3doZW4oDQogICAgcTJfdmFsdWUgJWluJSBjKCIxIiwgIjIiKSB+ICJOIiwNCiAgICBxMl92YWx1ZSAlaW4lIGMoIjMiLCAiNCIpIH4gIlkiDQogICkpDQoNCnN1cnZleV9xMl9jb250aW5nZW5jeSA8LSB0YWJsZShzdXJ2ZXlfcTIkcTJfcmVjb2RlLCBzdXJ2ZXlfcTIkZ3JvdXApDQojIHByaW50IHRoZSBjb250aW5nZW5jeSB0YWJsZQ0KcHJpbnQoc3VydmV5X3EyX2NvbnRpbmdlbmN5KQ0KIyBDaGktc3F1YXJlZCB0ZXN0DQpjaGlzcS50ZXN0KHN1cnZleV9xMl9jb250aW5nZW5jeSkNCg0KIyBjaGlzcV9yZXN1bHQgPC0gY2hpc3EudGVzdChzdXJ2ZXlfcTJfY29udGluZ2VuY3kpDQojIGNoaXNxX3Jlc3VsdCRzdGRyZXMgIA0KIyBjaGlzcV9yZXN1bHQkZXhwZWN0ZWQgIyhJZiBtYW55IHZhbHVlcyBhcmUgPCA1LCB5b3VyIENoaS1zcXVhcmVkIHRlc3QgbWF5IGJlIGxlc3MgcmVsaWFibGUuKQ0KIyBQb3N0LWhvYyB0ZXN0IGZvciBOIC0tPiBubyBzaW5nbGUgcGFpcndpc2UgZGlmZmVyZW5jZSBpcyBzdHJvbmcNCiMgcGFpcndpc2UucHJvcC50ZXN0KA0KIyAgIHggPSBzdXJ2ZXlfcTJfY29udGluZ2VuY3lbIk4iLCBdLA0KIyAgIG4gPSBjb2xTdW1zKHN1cnZleV9xMl9jb250aW5nZW5jeSksDQojICAgcC5hZGp1c3QubWV0aG9kID0gImhvbG0iDQojICkNCg0KYGBgDQoNClN1bW1hcnkgVGFibGUgb2YgcHJvcG9ydGlvbiBvZiB5ZXMgYW5kIG5vDQoNCmBgYHtyfQ0KeWVzX3BlciA8LSBzdXJ2ZXlfcTJfY29udGluZ2VuY3lbMixdDQpub19wZXIgPC0gc3VydmV5X3EyX2NvbnRpbmdlbmN5WzEsXQ0KZmFtaWxhcml0eV9ncm91cF90b3RhbCA8LSBjb2xTdW1zKHN1cnZleV9xMl9jb250aW5nZW5jeSkNCnllc19wcm9wIDwtIHllc19wZXIvZmFtaWxhcml0eV9ncm91cF90b3RhbA0Kbm9fcHJvcCA8LSBub19wZXIvZmFtaWxhcml0eV9ncm91cF90b3RhbA0KIyBjb252ZXJ0IHRvIGRhdGEgZnJhbWUNCnN1cnZleV9xMl9zdW1tYXJ5IDwtZGF0YS5mcmFtZSh5ZXNfcHJvcCwgbm9fcHJvcCkNCg0KYGBgDQoNClBsb3QgdGhlIGdyYXBoDQoNCmBgYHtyfQ0KZ2dwbG90KHN1cnZleV9xMiwgYWVzKHggPSBxMl9yZWNvZGUsIGZpbGwgPSBncm91cCkpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGxhYnModGl0bGUgPSAiSGF2ZSB5b3UgZXZlciBiZWVuIGNvbW11bmljYXRlZCB0aGlzIHR5cGUgb2YgaW5mb3JtYXRpb24gYmVmb3JlPyIsDQogICAgICAgeCA9ICJSZXNwb25zZSIsDQogICAgICAgeSA9ICJDb3VudCIpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQojIyBReHguMyBQcmlvciBFeHBlY3RhdGlvbg0KRG9lcyB0aGUgaW5mbGF0aW9uIGZvcmVjYXN0IGluZm9ybWF0aW9uIHByb3ZpZGVkIGFsaWduIHdpdGggeW91ciBleHBlY3RhdGlvbnM/XA0KVmFyaWFibGU6IGNhdGVnb3JpY2FsXA0KTWV0aG9kOiBDb250aW5nZW5jeSBUYWJsZSArIENoaS1zcXVhcmVkIHRlc3RcDQoqKlJlc3VsdDogRmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyoqDQpgYGB7cn0NCiMgY29tYmluZSBkYXRhIGZyb20gZGlmZmVyZW50IGdyb3Vwcw0Kc3VydmV5X3EzIDwtIGRhdGEuZnJhbWUoKQ0Kc3VydmV5X3EzX2xpc3QgPC0gbGlzdCgiUTQuMyIsIlE2LjMiLCAiUTguMyIsICJRMTAuMyIsICJRMTIuMyIpDQpmb3IgKGkgaW4gc2VxX2Fsb25nKGdyb3VwX2xpc3QpKSB7DQogIGRmIDwtIGdyb3VwX2xpc3RbW2ldXQ0KICBjb2wgPC0gc3VydmV5X3EzX2xpc3RbW2ldXQ0KICB0ZW1wX3RhYmxlIDwtIGRmWywgYyhjb2wsICJncm91cCIpXQ0KICBuYW1lcyh0ZW1wX3RhYmxlKSA8LSBjKCJxM192YWx1ZSIsICJncm91cCIpDQogIHN1cnZleV9xMyA8LSByYmluZChzdXJ2ZXlfcTMsIHRlbXBfdGFibGUpDQp9DQoNCiMgSW5pdGlhbCBDaGVjaw0Kc3VtbWFyeShhcy5udW1lcmljKHN1cnZleV9xMyRxM192YWx1ZSkpDQpgYGANClRlc3QgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gZ3JvdXBzDQpgYGB7cn0NCnN1cnZleV9xM19jb250aW5nZW5jeSA8LSB0YWJsZShzdXJ2ZXlfcTMkcTNfdmFsdWUsIHN1cnZleV9xMyRncm91cCkNCiMgcHJpbnQgdGhlIGNvbnRpbmdlbmN5IHRhYmxlDQpwcmludChzdXJ2ZXlfcTNfY29udGluZ2VuY3kpDQojIENoaS1zcXVhcmVkIHRlc3QNCmNoaXNxLnRlc3Qoc3VydmV5X3EzX2NvbnRpbmdlbmN5KQ0KYGBgDQpQbG90IHByaW9yIGV4cGVjdGF0aW9uIHByb3BvcnRpb24gYmFyIHBsb3QgYWNyb3NzIGRpZmZlcmVudCBncm91cHMNCmBgYHtyfQ0Kc3VydmV5X3EzX3Byb3AgIDwtIGFzLmRhdGEuZnJhbWUoc3VydmV5X3EzX2NvbnRpbmdlbmN5KQ0KIyByZW5hbWUgY29sdW1ucw0KbmFtZXMoc3VydmV5X3EzX3Byb3ApIDwtIGMoIlEzLjMiLCAiR3JvdXAiLCAiQ291bnQiKQ0KIyBhZGQgYSBsYWJlbGxlZCBjb2x1bW4NCnN1cnZleV9xM19wcm9wIDwtIHN1cnZleV9xM19wcm9wICU+JQ0KICBtdXRhdGUoUTMuM19sYWJlbCA9IGNhc2Vfd2hlbigNCiAgICBRMy4zID09ICIxIiB+ICIxLVN0cm9uZ2x5IGFsaWducyIsDQogICAgUTMuMyA9PSAiMiIgfiAiMi1Tb21ld2hhdCBhbGlnbnMiLA0KICAgIFEzLjMgPT0gIjMiIH4gIjMtTmV1dHJhbCIsDQogICAgUTMuMyA9PSAiNCIgfiAiNC1Tb21ld2hhdCBkb2VzIG5vdCBhbGlnbiIsDQogICAgUTMuMyA9PSAiNSIgfiAiNS1Eb2VzIG5vdCBhbGlnbiBhdCBhbGwiLA0KICApKQ0KIyBjYWxjdWxhdGUgcHJvcG9ydGlvbnMgd2l0aGluIGVhY2ggZ3JvdXANCnN1cnZleV9xM19wcm9wIDwtIHN1cnZleV9xM19wcm9wICU+JQ0KICBncm91cF9ieShHcm91cCkgJT4lDQogIG11dGF0ZShQcm9wb3J0aW9uID0gQ291bnQgLyBzdW0oQ291bnQpKQ0KZ2dwbG90KHN1cnZleV9xM19wcm9wLCBhZXMoeCA9IGFzLmZhY3RvcihgUTMuM19sYWJlbGApLCB5ID0gUHJvcG9ydGlvbiwgZmlsbCA9IEdyb3VwKSkgKyBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJRMy4zIFByaW9yIEV4cGVjdGF0aW9uIFByb3BvdGlvbiBQbG90IGFjcm9zcyBHcm91cHMiLA0KICAgIHggPSAiUmVzcG9uc2UiLA0KICAgIHkgPSAiUHJvcG9ydGlvbiINCiAgKSArDQogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANClBsb3QgcGllIGNoYXJ0IGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCnN1cnZleV9xM19zdW1tYXJ5IDwtIHN1cnZleV9xM19wcm9wICU+JQ0KICBncm91cF9ieShgUTMuM19sYWJlbGApICU+JQ0KICBzdW1tYXJpc2UodG90YWxfY291bnQgPSBzdW0oQ291bnQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSB0b3RhbF9jb3VudCAvIHN1bSh0b3RhbF9jb3VudCksDQogICAgICAgICBgUTMuM19ncmFwaF9sYWJlbGAgPSBwYXN0ZTAoYFEzLjNfbGFiZWxgLCAiICgiLCByb3VuZChwcm9wb3J0aW9uICogMTAwLCAyKSwgIiAlKSIpKQ0KZ2dwbG90KHN1cnZleV9xM19zdW1tYXJ5LCBhZXMoeCA9ICIiLHkgPSBwcm9wb3J0aW9uLCBmaWxsID0gYFEzLjNfZ3JhcGhfbGFiZWxgKSkgKw0KICBnZW9tX2NvbCh3aWR0aCA9IDEpICsNCiAgY29vcmRfcG9sYXIodGhldGEgPSAieSIpICsNCiAgbGFicyh0aXRsZSA9ICJRMy4zIFByaW9yIEV4cGVjdGF0aW9uIFN1bW1hcnkgUGllIENoYXJ0IiwNCiAgICAgICB4ID0gIiIsDQogICAgICAgeSA9ICIiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKQ0KYGBgDQojIyBReHguNCBDb25mbGljdGlvbiB3aXRoIFByaW9yIEV4cGVjdGF0aW9uDQpIb3cgZG9lcyB0aGUgaW5mbGF0aW9uIGZvcmVjYXN0IGNvbmZsaWN0IHdpdGggeW91ciBleHBlY3RhdGlvbnM/XA0KVmFyaWFibGU6IGNhdGVnb3JpY2FsXA0KTWV0aG9kOiBjYWxjdWxhdGUgdG90YWwgbnVtYmVyIG9mIHBlb3BsZSB3aG8gdGhpbmsgdGhlIGZvcmVjYXN0IGlzIG5vdCBhbGlnbmVkIHdpdGggdGhlaXIgZXhwZWN0YXRpb25cDQoqKlJlc3VsdDogQW1vbmcgcGVvcGxlIHdobyB0aGluayB0aGUgZm9yZWNhc3QgaXMgbm90IGFsaWduZWQgd2l0aCB0aGVpciBleHBlY3RhdGlvbiwgOTAlIHBlcmNlbnQgb2YgcmVzcG9uZGVudHMgdGhpbmtzIHRoZSBmb3JlY2FzdCBpcyBsb3dlciB0aGFuIHdoYXQgdGhleSBleHBlY3RlZC4qKg0KYGBge3J9DQojIENoZWNrIHRoZSBudW1iZXIgb2YgcGVvcGxlIGFuc3dlcmVkIHRoaXMgcXVlc3Rpb24NCm5fbm90X2FsaWduIDwtIHN1bShzdXJ2ZXlfcTNfc3VtbWFyeSR0b3RhbF9jb3VudFs0OjVdKQ0KIyBDb21iaW5lIGRhdGEgZnJvbSBkaWZmZXJlbnQgZ3JvdXBzDQpzdXJ2ZXlfcTQgPC0gZGF0YS5mcmFtZSgpDQpzdXJ2ZXlfcTRfbGlzdCA8LSBsaXN0KCJRNC40IiwiUTYuNCIsICJROC40IiwgIlExMC40IiwgIlExMi40IikNCmZvciAoaSBpbiBzZXFfYWxvbmcoZ3JvdXBfbGlzdCkpIHsNCiAgZGYgPC0gZ3JvdXBfbGlzdFtbaV1dDQogIGNvbCA8LSBzdXJ2ZXlfcTRfbGlzdFtbaV1dDQogIHRlbXBfdGFibGUgPC0gZGZbLCBjKGNvbCwgImdyb3VwIildDQogIG5hbWVzKHRlbXBfdGFibGUpIDwtIGMoInE0X3ZhbHVlIiwgImdyb3VwIikNCiAgc3VydmV5X3E0IDwtIHJiaW5kKHN1cnZleV9xNCwgdGVtcF90YWJsZSkNCn0NCnN1cnZleV9xNCA8LSBzdXJ2ZXlfcTRbIWlzLm5hKHN1cnZleV9xNCRxNF92YWx1ZSksIF0NCnN1cnZleV9xNF9jb250aW5nZW5jeSA8LSB0YWJsZShzdXJ2ZXlfcTQkcTRfdmFsdWUsIHN1cnZleV9xNCRncm91cCkNCiMgcHJpbnQgdGhlIGNvbnRpbmdlbmN5IHRhYmxlDQpwcmludChzdXJ2ZXlfcTRfY29udGluZ2VuY3kpDQoNCmBgYA0KUGxvdCBjb25mbGljdGlvbiB3aXRoIHByaW9yIGV4cGVjdGF0aW9uIHByb3BvcnRpb24gYmFyIHBsb3QgYWNyb3NzIGRpZmZlcmVudCBncm91cHMNCmBgYHtyfQ0Kc3VydmV5X3E0X3Byb3AgIDwtIGFzLmRhdGEuZnJhbWUoc3VydmV5X3E0X2NvbnRpbmdlbmN5KQ0KIyByZW5hbWUgY29sdW1ucw0KbmFtZXMoc3VydmV5X3E0X3Byb3ApIDwtIGMoIlE0LjQiLCAiR3JvdXAiLCAiQ291bnQiKQ0KIyBhZGQgYSBsYWJlbGxlZCBjb2x1bW4NCnN1cnZleV9xNF9wcm9wIDwtIHN1cnZleV9xNF9wcm9wICU+JQ0KICBtdXRhdGUoUTQuNF9sYWJlbCA9IGNhc2Vfd2hlbigNCiAgICBRNC40ID09ICIxIiB+ICIxLUhpZ2hlciB0aGFuIHdoYXQgSSBleHBlY3RlZCIsDQogICAgUTQuNCA9PSAiMiIgfiAiMi1Mb3dlciB0aGFuIHdoYXQgSSBleHBlY3RlZCINCiAgKSkNCiMgY2FsY3VsYXRlIHByb3BvcnRpb25zIHdpdGhpbiBlYWNoIGdyb3VwDQpzdXJ2ZXlfcTRfcHJvcCA8LSBzdXJ2ZXlfcTRfcHJvcCAlPiUNCiAgZ3JvdXBfYnkoR3JvdXApICU+JQ0KICBtdXRhdGUoUHJvcG9ydGlvbiA9IENvdW50IC8gc3VtKENvdW50KSkNCmdncGxvdChzdXJ2ZXlfcTRfcHJvcCwgYWVzKHggPSBhcy5mYWN0b3IoYFE0LjRfbGFiZWxgKSwgeSA9IFByb3BvcnRpb24sIGZpbGwgPSBHcm91cCkpICsgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUTQuNCBDb25mbGljdGlvbiB3aXRoIFByaW9yIEV4cGVjdGF0aW9uIFByb3BvdGlvbiBQbG90IGFjcm9zcyBHcm91cHMiLA0KICAgIHggPSAiUmVzcG9uc2UiLA0KICAgIHkgPSAiUHJvcG9ydGlvbiINCiAgKSArDQogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANClBsb3QgcGllIGNoYXJ0IGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCnN1cnZleV9xNF9zdW1tYXJ5IDwtIHN1cnZleV9xNF9wcm9wICU+JQ0KICBncm91cF9ieShgUTQuNF9sYWJlbGApICU+JQ0KICBzdW1tYXJpc2UodG90YWxfY291bnQgPSBzdW0oQ291bnQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSB0b3RhbF9jb3VudCAvIHN1bSh0b3RhbF9jb3VudCksDQogICAgICAgICBgUTQuNF9ncmFwaF9sYWJlbGAgPSBwYXN0ZTAoYFE0LjRfbGFiZWxgLCAiICgiLCByb3VuZChwcm9wb3J0aW9uICogMTAwLCAyKSwgIiAlKSIpKQ0KZ2dwbG90KHN1cnZleV9xNF9zdW1tYXJ5LCBhZXMoeCA9ICIiLHkgPSBwcm9wb3J0aW9uLCBmaWxsID0gYFE0LjRfZ3JhcGhfbGFiZWxgKSkgKw0KICBnZW9tX2NvbCh3aWR0aCA9IDEpICsNCiAgY29vcmRfcG9sYXIodGhldGEgPSAieSIpICsNCiAgbGFicyh0aXRsZSA9ICJRNC40IENvbmZsaWN0aW9uIHdpdGggUHJpb3IgRXhwZWN0YXRpb24gU3VtbWFyeSBQaWUgQ2hhcnQiLA0KICAgICAgIHggPSAiIiwNCiAgICAgICB5ID0gIiIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpDQpgYGANCiMjIFF4eC42IFByb2JhYmlsaXR5IG9mIGV4YWN0bHkgMi42JQ0Kd2hhdCBkbyB5b3UgdGhpbmsgaXMgdGhlIHByb2JhYmlsaXR5IG9mIGluZmxhdGlvbiBiZWluZyBleGFjdGx5IDIuNiU/XA0KRGVmaW5pdGl2ZSBDb3JyZWN0IEFuc3dlclwNCipkZXNjZW5kaW5nIG9yZGVyKlwNClZhcmlhYmxlOiBjYXRlZ29yaWNhbFwNCk1ldGhvZDogY29udGluZ2VuY3kgdGFibGUgJiBwcm9wb3J0aW9uIHRlc3RcDQoqKlJlc3VsdDogVGhlcmUgaXMgbm8gc3RhdGlzdGljYWwgZGlmZmVyZW5jZSBpbiB0ZXJtcyBvZiBjb3JyZWN0bHkgYW5zd2VyaW5nIHRoZSBwcm9iYWJpbGl0eSBvZiBpbmZsYXRpb24gYmVpbmcgZXhhY3RseSAyLjYlLioqDQpgYGB7cn0NCiMgY29tYmluZSBkYXRhIGZyb20gZGlmZmVyZW50IGdyb3Vwcw0Kc3VydmV5X3E2IDwtIGRhdGEuZnJhbWUoKQ0Kc3VydmV5X3E2X2xpc3QgPC0gbGlzdCgiUTQuNiIsIlE2LjYiLCAiUTguNiIsICJRMTAuNiIsICJRMTIuNiIpDQpmb3IgKGkgaW4gc2VxX2Fsb25nKGdyb3VwX2xpc3QpKSB7DQogIGRmIDwtIGdyb3VwX2xpc3RbW2ldXQ0KICBjb2wgPC0gc3VydmV5X3E2X2xpc3RbW2ldXQ0KICB0ZW1wX3RhYmxlIDwtIGRmWywgYyhjb2wsICJncm91cCIpXQ0KICBuYW1lcyh0ZW1wX3RhYmxlKSA8LSBjKCJxNl92YWx1ZSIsICJncm91cCIpDQogIHN1cnZleV9xNiA8LSByYmluZChzdXJ2ZXlfcTYsIHRlbXBfdGFibGUpDQp9DQpzdXJ2ZXlfcTYkcTZfdmFsdWUgPC0gYXMubnVtZXJpYyhzdXJ2ZXlfcTYkcTZfdmFsdWUpDQoNCnN1cnZleV9xNl9jb250aW5nZW5jeSA8LSB0YWJsZShzdXJ2ZXlfcTYkcTZfdmFsdWUsIHN1cnZleV9xNiRncm91cCkNCnByaW50KHN1cnZleV9xNl9jb250aW5nZW5jeSkNCg0KDQojIHdoZXRoZXIgb25lIHByb3BvcnRpb24gZGlmZmVycyBhY3Jvc3MgZ3JvdXBzDQpsZXNzX3RoYW5fMV9wZXIgPC0gc3VydmV5X3E2X2NvbnRpbmdlbmN5WzcsXQ0Kc3VydmV5X3E2X2dyb3VwX3RvdGFsIDwtIGNvbFN1bXMoc3VydmV5X3E2X2NvbnRpbmdlbmN5KQ0KcHJvcC50ZXN0KGxlc3NfdGhhbl8xX3Blciwgc3VydmV5X3E2X2dyb3VwX3RvdGFsKQ0KDQpgYGANClBsb3QgcHJvYmFiaWxpdHkgb2YgZXhhY3RseSAyLjYlIHByb3BvcnRpb24gYmFyIHBsb3QgYWNyb3NzIGRpZmZlcmVudCBncm91cHMNCmBgYHtyfQ0Kc3VydmV5X3E2X3Byb3AgIDwtIGFzLmRhdGEuZnJhbWUoc3VydmV5X3E2X2NvbnRpbmdlbmN5KQ0KIyByZW5hbWUgY29sdW1ucw0KbmFtZXMoc3VydmV5X3E2X3Byb3ApIDwtIGMoIlF4eC42IiwgIkdyb3VwIiwgIkNvdW50IikNCiMgYWRkIGEgbGFiZWxsZWQgY29sdW1uDQpzdXJ2ZXlfcTZfcHJvcCA8LSBzdXJ2ZXlfcTZfcHJvcCAlPiUNCiAgbXV0YXRlKFF4eC42X2xhYmVsID0gY2FzZV93aGVuKA0KICAgIFF4eC42ID09ICIxIiB+ICIxLT45OSUiLA0KICAgIFF4eC42ID09ICIyIiB+ICIyLWFyb3VuZCA4MCUiLA0KICAgIFF4eC42ID09ICIzIiB+ICIzLWFyb3VuZCA2MCUiLA0KICAgIFF4eC42ID09ICI0IiB+ICI0LWFyb3VuZCA1MCUiLA0KICAgIFF4eC42ID09ICI1IiB+ICI1LWFyb3VuZCAzMCUiLA0KICAgIFF4eC42ID09ICI2IiB+ICI2LWFyb3VuZCAyMCUiLA0KICAgIFF4eC42ID09ICI3IiB+ICI3LTwxJSINCiAgKSkNCiMgY2FsY3VsYXRlIHByb3BvcnRpb25zIHdpdGhpbiBlYWNoIGdyb3VwDQpzdXJ2ZXlfcTZfcHJvcCA8LSBzdXJ2ZXlfcTZfcHJvcCAlPiUNCiAgZ3JvdXBfYnkoR3JvdXApICU+JQ0KICBtdXRhdGUoUHJvcG9ydGlvbiA9IENvdW50IC8gc3VtKENvdW50KSkNCmdncGxvdChzdXJ2ZXlfcTZfcHJvcCwgYWVzKHggPSBhcy5mYWN0b3IoYFF4eC42X2xhYmVsYCksIHkgPSBQcm9wb3J0aW9uLCBmaWxsID0gR3JvdXApKSArIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICAjIGZhY2V0X3dyYXAofkdyb3VwKSsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJReHguNiBQcm9iYWJpbGl0eSBvZiBleGFjdGx5IDIuNiUgUHJvcG90aW9uIFBsb3QgYWNyb3NzIEdyb3VwcyIsDQogICAgeCA9ICJSZXNwb25zZSIsDQogICAgeSA9ICJQcm9wb3J0aW9uIg0KICApICsNCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KUGxvdCB0aGUgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCiMgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpnZ3Bsb3Qoc3VydmV5X3E2LCBhZXMoeCA9IHE2X3ZhbHVlKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEsIGZpbGwgPSAic3RlZWxibHVlIiwgY29sb3IgPSAid2hpdGUiKSArDQogIGxhYnModGl0bGUgPSAiUXh4LjYgUHJvYmFiaWxpdHkgb2YgZXhhY3RseSAyLjYlIEhpc3RvZ3JhbSIsDQogICAgICAgeCA9ICJSZXNwb25zZSIsDQogICAgICAgeSA9ICJDb3VudCIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCBtYXgoc3VydmV5X3E2JHE2X3ZhbHVlLCBuYS5ybSA9IFRSVUUpLCBieSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCg0KUGxvdCBwaWUgY2hhcnQgaW5jbHVkaW5nIGFsbCBwYXJ0aWNpcGFudHMNCmBgYHtyfQ0Kc3VydmV5X3E2X3N1bW1hcnkgPC0gc3VydmV5X3E2X3Byb3AgJT4lDQogIGdyb3VwX2J5KGBRNi42X2xhYmVsYCkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9jb3VudCA9IHN1bShDb3VudCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IHRvdGFsX2NvdW50IC8gc3VtKHRvdGFsX2NvdW50KSwNCiAgICAgICAgIGBRNi42X2dyYXBoX2xhYmVsYCA9IHBhc3RlMChgUTYuNl9sYWJlbGAsICIgKCIsIHJvdW5kKHByb3BvcnRpb24gKiAxMDAsIDIpLCAiICUpIikpDQpnZ3Bsb3Qoc3VydmV5X3E2X3N1bW1hcnksIGFlcyh4ID0gIiIseSA9IHByb3BvcnRpb24sIGZpbGwgPSBgUTYuNl9ncmFwaF9sYWJlbGApKSArDQogIGdlb21fY29sKHdpZHRoID0gMSkgKw0KICBjb29yZF9wb2xhcih0aGV0YSA9ICJ5IikgKw0KICBsYWJzKHRpdGxlID0gIlF4eC42IFByb2JhYmlsaXR5IG9mIGV4YWN0bHkgMi42JSBTdW1tYXJ5IFBpZSBDaGFydCIsDQogICAgICAgeCA9ICIiLA0KICAgICAgIHkgPSAiIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSkNCmBgYA0KDQojIyAhIFF4eC43IFByb2JhYmlsaXR5IG9mIGJldHdlZW4gMS45JSBhbmQgMy4zJQ0Kd2hhdCBkbyB5b3UgdGhpbmsgaXMgdGhlIHByb2JhYmlsaXR5IG9mIGluZmxhdGlvbiBiZWluZyBiZXR3ZWVuIDEuOSUgYW5kIDMuMyU/XA0KRGVmaW5pdGl2ZSBDb3JyZWN0IEFuc3dlclwNCipkZXNjZW5kaW5nIG9yZGVyKlwNCk1ldGhvZDogY29udGluZ2VuY3kgdGFibGUgJiBwcm9wb3J0aW9uIHRlc3RcDQoqKlJlc3VsdDogVGhlcmUgaXMgc3RhdGlzdGljYWwgZGlmZmVyZW5jZSBpbiBjb250cm9sIGdyb3VwIGluIHRlcm1zIG9mIHRoZSBwcm9wb3J0aW9uIG9mIHRoZSBjb3JyZWN0IGFuc3dlciBvZiBob3cgcGVvcGxlIHRoaW5rIHRoZSBwcm9iYWJpbGl0eSBvZiBpbmZsYXRpb24gYmVpbmcgYmV0d2VlbiAxLjklIGFuZCAzLjMlIGlzLiAqKlwNCmBgYHtyfQ0KIyBjb21iaW5lIGRhdGEgZnJvbSBkaWZmZXJlbnQgZ3JvdXBzDQpzdXJ2ZXlfcTcgPC0gZGF0YS5mcmFtZSgpDQpzdXJ2ZXlfcTdfbGlzdCA8LSBsaXN0KCJRNC43IiwiUTYuNyIsICJROC43IiwgIlExMC43IiwgIlExMi43IikNCmZvciAoaSBpbiBzZXFfYWxvbmcoZ3JvdXBfbGlzdCkpIHsNCiAgZGYgPC0gZ3JvdXBfbGlzdFtbaV1dDQogIGNvbCA8LSBzdXJ2ZXlfcTdfbGlzdFtbaV1dDQogIHRlbXBfdGFibGUgPC0gZGZbLCBjKGNvbCwgImdyb3VwIildDQogIG5hbWVzKHRlbXBfdGFibGUpIDwtIGMoInE3X3ZhbHVlIiwgImdyb3VwIikNCiAgc3VydmV5X3E3IDwtIHJiaW5kKHN1cnZleV9xNywgdGVtcF90YWJsZSkNCn0NCnN1cnZleV9xNyRxN192YWx1ZSA8LSBhcy5udW1lcmljKHN1cnZleV9xNyRxN192YWx1ZSkNCmBgYA0KDQpUZXN0IHRoZSBwcm9wb3J0aW9uIG9mIGNvcnJlY3QgYW5zd2VyDQpgYGB7cn0NCnN1cnZleV9xN19jb250aW5nZW5jeSA8LSB0YWJsZShzdXJ2ZXlfcTckcTdfdmFsdWUsIHN1cnZleV9xNyRncm91cCkNCiMgcHJpbnQgdGhlIGNvbnRpbmdlbmN5IHRhYmxlDQpwcmludChzdXJ2ZXlfcTdfY29udGluZ2VuY3kpDQojIGNvcnJlY3QgYW5zd2VyDQpzdXJ2ZXlfcTdfY29ycmVjdCA8LSBzdXJ2ZXlfcTdfY29udGluZ2VuY3lbNSxdDQpzdXJ2ZXlfcTdfZ3JvdXBfdG90YWwgPC0gY29sU3VtcyhzdXJ2ZXlfcTdfY29udGluZ2VuY3kpDQpwcm9wLnRlc3Qoc3VydmV5X3E3X2NvcnJlY3QsIHN1cnZleV9xN19ncm91cF90b3RhbCkNCiMgcGFpcndpc2UgcHJvcG9ydGlvbiB0ZXN0DQpwYWlyd2lzZS5wcm9wLnRlc3QoDQogIHggPSBzdXJ2ZXlfcTdfY29udGluZ2VuY3lbNSwgXSwNCiAgbiA9IGNvbFN1bXMoc3VydmV5X3E3X2NvbnRpbmdlbmN5KSwNCiAgcC5hZGp1c3QubWV0aG9kID0gImJvbmZlcnJvbmkiICMgb3IgImhvbG0iLCAiQkgiDQopDQpgYGANCg0KDQpQbG90IHByb2JhYmlsaXR5IG9mIGJldHdlZW4gMS45JSBhbmQgMy4zJSBwcm9wb3J0aW9uIGJhciBwbG90IGFjcm9zcyBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCnN1cnZleV9xN19wcm9wICA8LSBhcy5kYXRhLmZyYW1lKHN1cnZleV9xN19jb250aW5nZW5jeSkNCiMgcmVuYW1lIGNvbHVtbnMNCm5hbWVzKHN1cnZleV9xN19wcm9wKSA8LSBjKCJReHguNyIsICJHcm91cCIsICJDb3VudCIpDQojIGFkZCBhIGxhYmVsbGVkIGNvbHVtbg0Kc3VydmV5X3E3X3Byb3AgPC0gc3VydmV5X3E3X3Byb3AgJT4lDQogIG11dGF0ZShReHguN19sYWJlbCA9IGNhc2Vfd2hlbigNCiAgICBReHguNyA9PSAiMSIgfiAiMS0+OTklIiwNCiAgICBReHguNyA9PSAiMiIgfiAiMi1hcm91bmQgODAlIiwNCiAgICBReHguNyA9PSAiMyIgfiAiMy1hcm91bmQgNjAlIiwNCiAgICBReHguNyA9PSAiNCIgfiAiNC1hcm91bmQgNTAlIiwNCiAgICBReHguNyA9PSAiNSIgfiAiNS1hcm91bmQgMzAlIiwNCiAgICBReHguNyA9PSAiNiIgfiAiNi1hcm91bmQgMjAlIiwNCiAgICBReHguNyA9PSAiNyIgfiAiNy08MSUiDQogICkpDQojIGNhbGN1bGF0ZSBwcm9wb3J0aW9ucyB3aXRoaW4gZWFjaCBncm91cA0Kc3VydmV5X3E3X3Byb3AgPC0gc3VydmV5X3E3X3Byb3AgJT4lDQogIGdyb3VwX2J5KEdyb3VwKSAlPiUNCiAgbXV0YXRlKFByb3BvcnRpb24gPSBDb3VudCAvIHN1bShDb3VudCkpDQpnZ3Bsb3Qoc3VydmV5X3E3X3Byb3AsIGFlcyh4ID0gYXMuZmFjdG9yKGBReHguN19sYWJlbGApLCB5ID0gUHJvcG9ydGlvbiwgZmlsbCA9IEdyb3VwKSkgKyBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgIyBmYWNldF93cmFwKH5Hcm91cCkrDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUXh4LjcgUHJvYmFiaWxpdHkgb2YgYmV0d2VlbiAxLjklIGFuZCAzLjMlIFByb3BvdGlvbiBQbG90IGFjcm9zcyBHcm91cHMiLA0KICAgIHggPSAiUmVzcG9uc2UiLA0KICAgIHkgPSAiUHJvcG9ydGlvbiINCiAgKSArDQogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANClBsb3QgdGhlIGhpc3RvZ3JhbSBpbmNsdWRpbmcgYWxsIHBhcnRpY2lwYW50cw0KYGBge3J9DQojIGhpc3RvZ3JhbSBpbmNsdWRpbmcgYWxsIHBhcnRpY2lwYW50cw0KZ2dwbG90KHN1cnZleV9xNywgYWVzKHggPSBxN192YWx1ZSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxLCBmaWxsID0gInN0ZWVsYmx1ZSIsIGNvbG9yID0gIndoaXRlIikgKw0KICAjIGZhY2V0X3dyYXAofiBncm91cCkgKw0KICBsYWJzKHRpdGxlID0gIlF4eC43IFByb2JhYmlsaXR5IG9mIGJldHdlZW4gMS45JSBhbmQgMy4zJSBIaXN0b2dyYW0iLA0KICAgICAgIHggPSAiUXh4LjciLA0KICAgICAgIHkgPSAiQ291bnQiKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgbWF4KHN1cnZleV9xNyRxN192YWx1ZSwgbmEucm0gPSBUUlVFKSwgYnkgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoNCiMjIFF4eC44IFByb2JhYmlsaXR5IG9mIGJldHdlZW4gMy4zJSBhbmQgNS42JQ0Kd2hhdCBkbyB5b3UgdGhpbmsgaXMgdGhlIHByb2JhYmlsaXR5IG9mIGluZmxhdGlvbiBiZWluZyBiZXR3ZWVuIDMuMyUgYW5kIDUuNiU/XA0KRGVmaW5pdGl2ZSBDb3JyZWN0IEFuc3dlclwNCipkZXNjZW5kaW5nIG9yZGVyKlwNCk1ldGhvZDogY29udGluZ2VuY3kgdGFibGUgJiBwcm9wb3J0aW9uIHRlc3RcDQoqKlJlc3VsdDogVGhlIGNvbnRyb2wgZ3JvdXAgYW5kIHRoZSBlcnJvciBiYXIgZ3JvdXAgaGFzIHNob3duIHN0YXRpc3RpY2FsIGRpZmZlcmVuY2UuKipcDQpgYGB7cn0NCiMgY29tYmluZSBkYXRhIGZyb20gZGlmZmVyZW50IGdyb3Vwcw0Kc3VydmV5X3E4IDwtIGRhdGEuZnJhbWUoKQ0Kc3VydmV5X3E4X2xpc3QgPC0gbGlzdCgiUTQuOCIsIlE2LjgiLCAiUTguOCIsICJRMTAuOCIsICJRMTIuOCIpDQpmb3IgKGkgaW4gc2VxX2Fsb25nKGdyb3VwX2xpc3QpKSB7DQogIGRmIDwtIGdyb3VwX2xpc3RbW2ldXQ0KICBjb2wgPC0gc3VydmV5X3E4X2xpc3RbW2ldXQ0KICB0ZW1wX3RhYmxlIDwtIGRmWywgYyhjb2wsICJncm91cCIpXQ0KICBuYW1lcyh0ZW1wX3RhYmxlKSA8LSBjKCJxOF92YWx1ZSIsICJncm91cCIpDQogIHN1cnZleV9xOCA8LSByYmluZChzdXJ2ZXlfcTgsIHRlbXBfdGFibGUpDQp9DQpzdXJ2ZXlfcTgkcThfdmFsdWUgPC0gYXMubnVtZXJpYyhzdXJ2ZXlfcTgkcThfdmFsdWUpDQoNCmBgYA0KDQpjb250aW5nZW5jeSB0YWJsZQ0KYGBge3J9DQpzdXJ2ZXlfcThfY29udGluZ2VuY3kgPC0gdGFibGUoc3VydmV5X3E4JHE4X3ZhbHVlLCBzdXJ2ZXlfcTgkZ3JvdXApDQojIHByaW50IHRoZSBjb250aW5nZW5jeSB0YWJsZQ0KcHJpbnQoc3VydmV5X3E4X2NvbnRpbmdlbmN5KQ0KIyBjb3JyZWN0IGFuc3dlcg0Kc3VydmV5X3E4X2NvcnJlY3QgPC0gc3VydmV5X3E4X2NvbnRpbmdlbmN5WzUsXQ0Kc3VydmV5X3E4X2dyb3VwX3RvdGFsIDwtIGNvbFN1bXMoc3VydmV5X3E4X2NvbnRpbmdlbmN5KQ0KcHJvcC50ZXN0KHN1cnZleV9xOF9jb3JyZWN0LCBzdXJ2ZXlfcThfZ3JvdXBfdG90YWwpDQojIHBhaXJ3aXNlIHByb3BvcnRpb24gdGVzdA0KcGFpcndpc2UucHJvcC50ZXN0KA0KICB4ID0gc3VydmV5X3E4X2NvbnRpbmdlbmN5WzUsIF0sDQogIG4gPSBjb2xTdW1zKHN1cnZleV9xOF9jb250aW5nZW5jeSksDQogIHAuYWRqdXN0Lm1ldGhvZCA9ICJib25mZXJyb25pIiAjIG9yICJob2xtIiwgIkJIIg0KKQ0KDQoNCmBgYA0KUGxvdCBwcm9iYWJpbGl0eSBvZiBiZXR3ZWVuIDMuMyUgYW5kIDUuNiUgcHJvcG9ydGlvbiBiYXIgcGxvdCBhY3Jvc3MgZGlmZmVyZW50IGdyb3Vwcw0KYGBge3J9DQpzdXJ2ZXlfcThfcHJvcCAgPC0gYXMuZGF0YS5mcmFtZShzdXJ2ZXlfcThfY29udGluZ2VuY3kpDQojIHJlbmFtZSBjb2x1bW5zDQpuYW1lcyhzdXJ2ZXlfcThfcHJvcCkgPC0gYygiUXh4LjgiLCAiR3JvdXAiLCAiQ291bnQiKQ0KIyBhZGQgYSBsYWJlbGxlZCBjb2x1bW4NCnN1cnZleV9xOF9wcm9wIDwtIHN1cnZleV9xOF9wcm9wICU+JQ0KICBtdXRhdGUoUXh4LjhfbGFiZWwgPSBjYXNlX3doZW4oDQogICAgUXh4LjggPT0gIjEiIH4gIjEtPjk5JSIsDQogICAgUXh4LjggPT0gIjIiIH4gIjItYXJvdW5kIDgwJSIsDQogICAgUXh4LjggPT0gIjMiIH4gIjMtYXJvdW5kIDYwJSIsDQogICAgUXh4LjggPT0gIjQiIH4gIjQtYXJvdW5kIDUwJSIsDQogICAgUXh4LjggPT0gIjUiIH4gIjUtYXJvdW5kIDMwJSIsDQogICAgUXh4LjggPT0gIjYiIH4gIjYtYXJvdW5kIDIwJSIsDQogICAgUXh4LjggPT0gIjciIH4gIjctPDElIg0KICApKQ0KIyBjYWxjdWxhdGUgcHJvcG9ydGlvbnMgd2l0aGluIGVhY2ggZ3JvdXANCnN1cnZleV9xOF9wcm9wIDwtIHN1cnZleV9xOF9wcm9wICU+JQ0KICBncm91cF9ieShHcm91cCkgJT4lDQogIG11dGF0ZShQcm9wb3J0aW9uID0gQ291bnQgLyBzdW0oQ291bnQpKQ0KZ2dwbG90KHN1cnZleV9xOF9wcm9wLCBhZXMoeCA9IGFzLmZhY3RvcihgUXh4LjhfbGFiZWxgKSwgeSA9IFByb3BvcnRpb24sIGZpbGwgPSBHcm91cCkpICsgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogICMgZmFjZXRfd3JhcCh+R3JvdXApKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlF4eC44IFByb2JhYmlsaXR5IG9mIGJldHdlZW4gMy4zJSBhbmQgNS42JSBQcm9wb3Rpb24gUGxvdCBhY3Jvc3MgR3JvdXBzIiwNCiAgICB4ID0gIlJlc3BvbnNlIiwNCiAgICB5ID0gIlByb3BvcnRpb24iDQogICkgKw0KICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIikrDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQpQbG90IHRoZSBoaXN0b2dyYW0gaW5jbHVkaW5nIGFsbCBwYXJ0aWNpcGFudHMNCmBgYHtyfQ0KIyBoaXN0b2dyYW0gaW5jbHVkaW5nIGFsbCBwYXJ0aWNpcGFudHMNCmdncGxvdChzdXJ2ZXlfcTgsIGFlcyh4ID0gcThfdmFsdWUpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMSwgZmlsbCA9ICJzdGVlbGJsdWUiLCBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgIyBmYWNldF93cmFwKH4gZ3JvdXApICsNCiAgbGFicyh0aXRsZSA9ICJReHguOCBQcm9iYWJpbGl0eSBvZiBiZXR3ZWVuIDMuMyUgYW5kIDUuNiUgSGlzdG9ncmFtIiwNCiAgICAgICB4ID0gIlF4eC44IiwNCiAgICAgICB5ID0gIkNvdW50IikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIG1heChzdXJ2ZXlfcTgkcThfdmFsdWUsIG5hLnJtID0gVFJVRSksIGJ5ID0gMSkpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCiMjICEgUXh4LjEwIFByb2JhYmlsaXR5IG9mIGVuZGluZyBvdXRzaWRlIHRoZSByYW5nZQ0KQmFzZWQgb24gdGhlIGluZmxhdGlvbiBmb3JlY2FzdCBwcm92aWRlZCwgd2hhdCBkbyB5b3UgdGhpbmsgaXMgdGhlIHByb2JhYmlsaXR5IG9mIGluZmxhdGlvbiBlbmRpbmcgdXAgb3V0c2lkZSBvZiAgdGhlIHJhbmdlIGZyb20gLTAuNCUgdG8gNS42JT9cDQpEZWZpbml0aXZlIENvcnJlY3QgQW5zd2VyICh2YXJpZWQgYmV0d2VlbiBncm91cClcDQoqZGVzY2VuZGluZyBvcmRlcipcDQpWYXJpYWJsZTogY2F0ZWdvcmljYWxcDQpNZXRob2Q6IGNhbGN1bGF0ZSB0aGUgcHJvcG9ydGlvbiBmb3IgZWFjaCBncm91cCArIHByb3BvcnRpb24gdGVzdFwNCioqUmVzdWx0OiBDb250cm9sIGdyb3VwIHBlcmZvcm0gc2lnbmlmaWNhbnQgd29yc2UgdGhhbiBvdGhlciBncm91cHMuKipcDQpgYGB7cn0NCnN1cnZleV9xMTAgPC0gZGF0YS5mcmFtZSgNCiAgZ3JvdXAgICA9IGNoYXJhY3RlcigwKSwNCiAgY29ycmVjdCA9IGludGVnZXIoMCksDQogIHRvdGFsICAgPSBpbnRlZ2VyKDApLA0KICBwcm9wICAgID0gbnVtZXJpYygwKQ0KKQ0Kc3VydmV5X3ExMF9saXN0IDwtIGxpc3QoIlE0LjEwIiwiUTYuMTAiLCAiUTguMTAiLCAiUTEwLjEwIiwgIlExMi4xMCIpDQpzdXJ2ZXlfcTEwX2NvcnJlY3QgPC1jKDgsMTIsMTQsMTQsMTQpICMgMTAlLCA0MCUuIDEwJSwgMTAlLCAxMCUNCg0KZm9yIChpIGluIHNlcV9hbG9uZyhncm91cF9saXN0KSkgew0KICBkZiA8LSBncm91cF9saXN0W1tpXV0NCiAgY29sIDwtIHN1cnZleV9xMTBfbGlzdFtbaV1dDQogIHExMF9jb3JyZWN0IDwtIHN1cnZleV9xMTBfY29ycmVjdFtpXQ0KICANCiAgIyBjb3VudCB0b3RhbCBudW1iZXIgb2YgcGVvcGxlIGluIGVhY2ggZ3JvdXANCiAgdG90YWxfY291bnQgPC0gbnJvdyhkZikNCiAgIyBjb3VudCBudW1iZXIgb2YgcGVvcGxlIHdobyBhbnN3ZXJlZCBjb3JyZWN0bHkNCiAgY29ycmVjdF9jb3VudCA8LSBzdW0oZGZbLCBjb2xdID09IHExMF9jb3JyZWN0LCBuYS5ybSA9IFRSVUUpDQogICMgY29tcHV0ZSB0aGUgcHJvcG9ydGlvbg0KICBwcm9wIDwtIGNvcnJlY3RfY291bnQgLyB0b3RhbF9jb3VudA0KICAjIGNhcHR1cmUgdGhlIGdyb3VwIG5hbWUNCiAgZ3JwX2xhYmVsIDwtIG5hbWVzKGdyb3VwX2xpc3RbaV0pICANCiAgIyByb3ctYmluZCBpbnRvIHN1cnZleV9xMTANCiAgc3VydmV5X3ExMCA8LSByYmluZChzdXJ2ZXlfcTEwLCBkYXRhLmZyYW1lKA0KICAgIGdyb3VwID0gZ3JwX2xhYmVsLA0KICAgIGNvcnJlY3QgPSBjb3JyZWN0X2NvdW50LA0KICAgIHRvdGFsID0gdG90YWxfY291bnQsDQogICAgcHJvcCA9IHByb3ApKQ0KfQ0KDQojIHByb3BvcnRpb24gdGVzdCAtLT4gVGhlcmUgaXMgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZQ0KcHJvcC50ZXN0KHggPSBzdXJ2ZXlfcTEwJGNvcnJlY3QsDQogICAgICAgICAgbiA9IHN1cnZleV9xMTAkdG90YWwpDQojIHBhaXJ3aXNlIHByb3BvcnRpb24gdGVzdA0KcGFpcndpc2UucHJvcC50ZXN0KA0KICB4ID0gc2V0TmFtZXMoc3VydmV5X3ExMCRjb3JyZWN0LCBzdXJ2ZXlfcTEwJGdyb3VwKSwNCiAgbiA9IHNldE5hbWVzKHN1cnZleV9xMTAkdG90YWwsICAgc3VydmV5X3ExMCRncm91cCksDQogIHAuYWRqdXN0Lm1ldGhvZCA9ICJib25mZXJyb25pIiAjIG9yICJob2xtIiwgIkJIIg0KKQ0KYGBgDQoNCmBgYHtyfQ0KDQpnZ3Bsb3Qoc3VydmV5X3ExMCwgYWVzKHggPSBncm91cCwgeSA9IHByb3ApKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gInN0ZWVsYmx1ZSIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNjYWxlczo6cGVyY2VudChwcm9wLCBhY2N1cmFjeSA9IDEpKSwgdmp1c3QgPSAtMC41KSArDQogIGxhYnModGl0bGUgPSAiUXh4LjEwIFByb2JhYmlsaXR5IG9mIGVuZGluZyBvdXRzaWRlIHRoZSByYW5nZSBjb3JyZWN0IGFuc3dlciByYXRlIiwNCiAgICAgICB4ID0gIkdyb3VwIiwNCiAgICAgICB5ID0gIlByb3BvcnRpb24iKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANClBsb3QgZGlzdHJpYnV0aW9uIGZvciBlYWNoIGluZGl2aWR1YWwgZ3JvdXANCmBgYHtyfQ0KZ2dwbG90KGNvbnRyb2xsZWRfZ3JvdXAsIGFlcyh4ID0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoUTQuMTApKSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxLCBmaWxsID0gInN0ZWVsYmx1ZSIsIGNvbG9yID0gIndoaXRlIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoDQogICAgbGltaXRzID0gYygwLCA1MCksICAgICAgICAjIGZvcmNlIHkgZnJvbSAwIHVwIHRvIDYwDQogICAgYnJlYWtzID0gc2VxKDAsIDUwLCBieT0xMCkgIyB0aWNrcyBhdCAwLCAxMCwgMjAsIOKApiwgNjANCiAgKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSAuLmNvdW50Li4pLCBzdGF0ID0gImNvdW50Iiwgdmp1c3QgPSAtMC41KSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiQ29udHJvbGxlZCBHcm91cDogRGlzdHJpYnV0aW9uIG9mIFE0LjEwIFJlc3BvbnNlcyIsDQogICAgeCAgICAgPSAiUTQuMTAgKG51bWVyaWMpIiwNCiAgICB5ICAgICA9ICJDb3VudCINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQojIyBReHguMTEgUHJvYmFiaWxpdHkgb2YgaGlnaGVyIHRoYW4gNiUNCkJhc2VkIG9uIHRoZSBpbmZsYXRpb24gZm9yZWNhc3QgcHJvdmlkZWQsIHdoYXQgZG8geW91IHRoaW5rIGlzIHRoZSBwcm9iYWJpbGl0eSBvZiBpbmZsYXRpb24gZW5kaW5nIHVwIGhpZ2hlciB0aGFuIDYlP1wNCkRlZmluaXRpdmUgQ29ycmVjdCBBbnN3ZXIgLSAzXA0KdmFyaWFibGU6IGNhdGVnb3JpY2FsXA0KTWV0aG9kOiBjb250aW5nZW5jeSB0YWJsZSAmIHByb3BvcnRpb24gdGVzdFwNCioqUmVzdWx0OiBUaGUgYmVsbCBjdXJ2ZSBhbmQgdGhlIGNvbnRyb2wgZ3JvdXAgaGFzIHNob3duIHNpZ25pZmljYW50IGRpZmZlcmVuY2UuIFRoZSBtYWpvcml0eSBwZW9wbGUgdGhpbmsgdGhlIHByb2JhYmlsaXR5IGlzIGV4dHJlbWVseSBsb3cgKGxlc3MgdGhhbiAxJSkuKipcDQpgYGB7cn0NCiMgY29tYmluZSBkYXRhIGZyb20gZGlmZmVyZW50IGdyb3Vwcw0Kc3VydmV5X3ExMSA8LSBkYXRhLmZyYW1lKCkNCnN1cnZleV9xMTFfbGlzdCA8LSBsaXN0KCJRNC4xMSIsIlE2LjExIiwgIlE4LjExIiwgIlExMC4xMSIsICJRMTIuMTEiKQ0KZm9yIChpIGluIHNlcV9hbG9uZyhncm91cF9saXN0KSkgew0KICBkZiA8LSBncm91cF9saXN0W1tpXV0NCiAgY29sIDwtIHN1cnZleV9xMTFfbGlzdFtbaV1dDQogIHRlbXBfdGFibGUgPC0gZGZbLCBjKGNvbCwgImdyb3VwIildDQogIG5hbWVzKHRlbXBfdGFibGUpIDwtIGMoInExMV92YWx1ZSIsICJncm91cCIpDQogIHN1cnZleV9xMTEgPC0gcmJpbmQoc3VydmV5X3ExMSwgdGVtcF90YWJsZSkNCn0NCnN1cnZleV9xMTEkcTExX3ZhbHVlIDwtIGFzLm51bWVyaWMoc3VydmV5X3ExMSRxMTFfdmFsdWUpDQoNCmBgYA0KDQpUZXN0IHRoZSBwcm9wb3J0aW9uIG9mIGNvcnJlY3QgYW5zd2VyDQpgYGB7cn0NCnN1cnZleV9xMTFfY29udGluZ2VuY3kgPC0gdGFibGUoc3VydmV5X3ExMSRxMTFfdmFsdWUsIHN1cnZleV9xMTEkZ3JvdXApDQojIHByaW50IHRoZSBjb250aW5nZW5jeSB0YWJsZQ0KcHJpbnQoc3VydmV5X3ExMV9jb250aW5nZW5jeSkNCnN1cnZleV9xMTFfY29ycmVjdCA8LSBzdXJ2ZXlfcTExX2NvbnRpbmdlbmN5WzMsXQ0Kc3VydmV5X3ExMV9ncm91cF90b3RhbCA8LSBjb2xTdW1zKHN1cnZleV9xMTFfY29udGluZ2VuY3kpDQpwcm9wLnRlc3Qoc3VydmV5X3ExMV9jb3JyZWN0LCBzdXJ2ZXlfcTExX2dyb3VwX3RvdGFsKQ0KDQpgYGANClBvc3QtaG9jIHRlc3QNCmBgYHtyfQ0KcGFpcndpc2UucHJvcC50ZXN0KA0KICB4ID0gc3VydmV5X3ExMV9jb250aW5nZW5jeVszLCBdLA0KICBuID0gY29sU3VtcyhzdXJ2ZXlfcTExX2NvbnRpbmdlbmN5KSwNCiAgcC5hZGp1c3QubWV0aG9kID0gImJvbmZlcnJvbmkiICMgb3IgImhvbG0iLCAiQkgiDQopDQpgYGANClBsb3QgcHJvYmFiaWxpdHkgb2YgaGlnaGVyIHRoYW4gNiUgcHJvcG9ydGlvbiBiYXIgcGxvdCBhY3Jvc3MgZGlmZmVyZW50IGdyb3Vwcw0KYGBge3J9DQpzdXJ2ZXlfcTExX3Byb3AgIDwtIGFzLmRhdGEuZnJhbWUoc3VydmV5X3ExMV9jb250aW5nZW5jeSkNCiMgcmVuYW1lIGNvbHVtbnMNCm5hbWVzKHN1cnZleV9xMTFfcHJvcCkgPC0gYygiUXh4LjExIiwgIkdyb3VwIiwgIkNvdW50IikNCiMgYWRkIGEgbGFiZWxsZWQgY29sdW1uDQpzdXJ2ZXlfcTExX3Byb3AgPC0gc3VydmV5X3ExMV9wcm9wICU+JQ0KICBtdXRhdGUoUXh4LjExX2xhYmVsID0gY2FzZV93aGVuKA0KICAgIFF4eC4xMSA9PSAiMSIgfiAiMS1Nb3JlIHRoYW4gMjAlIiwNCiAgICBReHguMTEgPT0gIjIiIH4gIjMtNS0xMCUiLA0KICAgIFF4eC4xMSA9PSAiMyIgfiAiNC0xLTUlIiwNCiAgICBReHguMTEgPT0gIjQiIH4gIjUtTGVzcyB0aGFuIDElIiwNCiAgICBReHguMTEgPT0gIjUiIH4gIjItMTAtMjAlIg0KICApKQ0KIyBjYWxjdWxhdGUgcHJvcG9ydGlvbnMgd2l0aGluIGVhY2ggZ3JvdXANCnN1cnZleV9xMTFfcHJvcCA8LSBzdXJ2ZXlfcTExX3Byb3AgJT4lDQogIGdyb3VwX2J5KEdyb3VwKSAlPiUNCiAgbXV0YXRlKFByb3BvcnRpb24gPSBDb3VudCAvIHN1bShDb3VudCkpDQpnZ3Bsb3Qoc3VydmV5X3ExMV9wcm9wLCBhZXMoeCA9IGFzLmZhY3RvcihgUXh4LjExX2xhYmVsYCksIHkgPSBQcm9wb3J0aW9uLCBmaWxsID0gR3JvdXApKSArIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICAjIGZhY2V0X3dyYXAofkdyb3VwKSsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJReHguMTEgUHJvYmFiaWxpdHkgb2YgaGlnaGVyIHRoYW4gNiUgUHJvcG90aW9uIFBsb3QgYWNyb3NzIEdyb3VwcyIsDQogICAgeCA9ICJSZXNwb25zZSIsDQogICAgeSA9ICJQcm9wb3J0aW9uIg0KICApICsNCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KUGxvdCB0aGUgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCiMgZm9yY2Ugb3JkZXIgZm9yIGdyYXBoDQpzdXJ2ZXlfcTExIDwtIHN1cnZleV9xMTEgJT4lDQogIG11dGF0ZSgNCiAgICBxMTFfdmFsdWVfcmUgPSBmYWN0b3IoDQogICAgICBxMTFfdmFsdWUsDQogICAgICBsZXZlbHMgPSBjKDEsIDUsIDIsIDMsIDQpDQogICAgKQ0KICApDQojIGhpc3RvZ3JhbSBpbmNsdWRpbmcgYWxsIHBhcnRpY2lwYW50cw0KZ2dwbG90KHN1cnZleV9xMTEsIGFlcyh4ID0gcTExX3ZhbHVlX3JlKSkgKw0KICBnZW9tX2JhcihmaWxsID0gInN0ZWVsYmx1ZSIsIGNvbG9yID0gIndoaXRlIikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlF4eC4xMSBSZXNwb25zZXMgKGZvcmNlZCAxLTUtMi0zLTQgb3JkZXIpIiwNCiAgICB4ICAgICA9ICJReHguMTEiLA0KICAgIHkgICAgID0gIkNvdW50Ig0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCiMjIFF4eC4xMiBQcm9iYWJpbGl0eSBvZiBoaWdoZXIgdGhhbiAzJSANCkJhc2VkIG9uIHRoZSBpbmZsYXRpb24gZm9yZWNhc3QgcHJvdmlkZWQsIHdoYXQgZG8geW91IHRoaW5rIGlzIHRoZSBwcm9iYWJpbGl0eSBvZiBpbmZsYXRpb24gZW5kaW5nIHVwIGhpZ2hlciB0aGFuIDMlP1wNCkRlZmluaXRpdmUgQ29ycmVjdCBBbnN3ZXIgLSAxXA0KdmFyaWFibGU6IGNhdGVnb3JpY2FsXA0KTWV0aG9kOiBjb250aW5nZW5jeSB0YWJsZSAmIHByb3BvcnRpb24gdGVzdFwNCioqUmVzdWx0OiBUaGVyZSBpcyBubyBzdGF0aXN0aWNhbCBkaWZmZXJlbmNlIGFuZCB0aGUgbWFqb3JpdHkgcGVvcGxlIGRpZG4ndCBnZXQgdGhlIGFuc3dlciByaWdodC4qKg0KYGBge3J9DQojIGNvbWJpbmUgZGF0YSBmcm9tIGRpZmZlcmVudCBncm91cHMNCnN1cnZleV9xMTIgPC0gZGF0YS5mcmFtZSgpDQpzdXJ2ZXlfcTEyX2xpc3QgPC0gbGlzdCgiUTQuMTIiLCJRNi4xMiIsICJROC4xMiIsICJRMTAuMTIiLCAiUTEyLjEyIikNCmZvciAoaSBpbiBzZXFfYWxvbmcoZ3JvdXBfbGlzdCkpIHsNCiAgZGYgPC0gZ3JvdXBfbGlzdFtbaV1dDQogIGNvbCA8LSBzdXJ2ZXlfcTEyX2xpc3RbW2ldXQ0KICB0ZW1wX3RhYmxlIDwtIGRmWywgYyhjb2wsICJncm91cCIpXQ0KICBuYW1lcyh0ZW1wX3RhYmxlKSA8LSBjKCJxMTJfdmFsdWUiLCAiZ3JvdXAiKQ0KICBzdXJ2ZXlfcTEyIDwtIHJiaW5kKHN1cnZleV9xMTIsIHRlbXBfdGFibGUpDQp9DQpzdXJ2ZXlfcTEyJHExMl92YWx1ZSA8LSBhcy5udW1lcmljKHN1cnZleV9xMTIkcTEyX3ZhbHVlKQ0KDQpgYGANCg0KVGVzdCB0aGUgcHJvcG9ydGlvbiBvZiBjb3JyZWN0IGFuc3dlcg0KYGBge3J9DQpzdXJ2ZXlfcTEyX2NvbnRpbmdlbmN5IDwtIHRhYmxlKHN1cnZleV9xMTIkcTEyX3ZhbHVlLCBzdXJ2ZXlfcTEyJGdyb3VwKQ0KIyBwcmludCB0aGUgY29udGluZ2VuY3kgdGFibGUNCnByaW50KHN1cnZleV9xMTJfY29udGluZ2VuY3kpDQoNCnN1cnZleV9xMTJfY29ycmVjdCA8LSBzdXJ2ZXlfcTEyX2NvbnRpbmdlbmN5WzIsXQ0Kc3VydmV5X3ExMl9ncm91cF90b3RhbCA8LSBjb2xTdW1zKHN1cnZleV9xMTJfY29udGluZ2VuY3kpDQpwcm9wLnRlc3Qoc3VydmV5X3ExMl9jb3JyZWN0LCBzdXJ2ZXlfcTEyX2dyb3VwX3RvdGFsKQ0KYGBgDQpQbG90IHByb2JhYmlsaXR5IG9mIGhpZ2hlciB0aGFuIDMlIHByb3BvcnRpb24gYmFyIHBsb3QgYWNyb3NzIGRpZmZlcmVudCBncm91cHMNCmBgYHtyfQ0Kc3VydmV5X3ExMl9wcm9wICA8LSBhcy5kYXRhLmZyYW1lKHN1cnZleV9xMTJfY29udGluZ2VuY3kpDQojIHJlbmFtZSBjb2x1bW5zDQpuYW1lcyhzdXJ2ZXlfcTEyX3Byb3ApIDwtIGMoIlF4eC4xMiIsICJHcm91cCIsICJDb3VudCIpDQojIGFkZCBhIGxhYmVsbGVkIGNvbHVtbg0Kc3VydmV5X3ExMl9wcm9wIDwtIHN1cnZleV9xMTJfcHJvcCAlPiUNCiAgbXV0YXRlKFF4eC4xMl9sYWJlbCA9IGNhc2Vfd2hlbigNCiAgICBReHguMTIgPT0gIjEiIH4gIjEtTW9yZSB0aGFuIDYwJSIsDQogICAgUXh4LjEyID09ICIyIiB+ICIzLTQwLTUwJSIsDQogICAgUXh4LjEyID09ICIzIiB+ICI0LTMwLTQwJSIsDQogICAgUXh4LjEyID09ICI0IiB+ICI1LUxlc3MgdGhhbiAzMCUiLA0KICAgIFF4eC4xMiA9PSAiNSIgfiAiMi01MC02MCUiDQogICkpDQojIGNhbGN1bGF0ZSBwcm9wb3J0aW9ucyB3aXRoaW4gZWFjaCBncm91cA0Kc3VydmV5X3ExMl9wcm9wIDwtIHN1cnZleV9xMTJfcHJvcCAlPiUNCiAgZ3JvdXBfYnkoR3JvdXApICU+JQ0KICBtdXRhdGUoUHJvcG9ydGlvbiA9IENvdW50IC8gc3VtKENvdW50KSkNCmdncGxvdChzdXJ2ZXlfcTEyX3Byb3AsIGFlcyh4ID0gYXMuZmFjdG9yKGBReHguMTJfbGFiZWxgKSwgeSA9IFByb3BvcnRpb24sIGZpbGwgPSBHcm91cCkpICsgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogICMgZmFjZXRfd3JhcCh+R3JvdXApKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlF4eC4xMiBQcm9iYWJpbGl0eSBvZiBoaWdoZXIgdGhhbiAzJSBQcm9wb3Rpb24gUGxvdCBhY3Jvc3MgR3JvdXBzIiwNCiAgICB4ID0gIlJlc3BvbnNlIiwNCiAgICB5ID0gIlByb3BvcnRpb24iDQogICkgKw0KICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIikrDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQpQbG90IHRoZSBoaXN0b2dyYW0gaW5jbHVkaW5nIGFsbCBwYXJ0aWNpcGFudHMNCmBgYHtyfQ0KIyBmb3JjZSBvcmRlciBmb3IgZ3JhcGgNCnN1cnZleV9xMTIgPC0gc3VydmV5X3ExMiAlPiUNCiAgbXV0YXRlKA0KICAgIHExMl92YWx1ZV9yZSA9IGZhY3RvcigNCiAgICAgIHExMl92YWx1ZSwNCiAgICAgIGxldmVscyA9IGMoMSwgNSwgMiwgMywgNCkNCiAgICApDQogICkNCiMgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpnZ3Bsb3Qoc3VydmV5X3ExMiwgYWVzKHggPSBxMTJfdmFsdWVfcmUpKSArDQogIGdlb21fYmFyKGZpbGwgPSAic3RlZWxibHVlIiwgY29sb3IgPSAid2hpdGUiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUXh4LjEyIFJlc3BvbnNlcyAoZm9yY2VkIDEtNS0yLTMtNCBvcmRlcikiLA0KICAgIHggICAgID0gIlF4eC4xMiIsDQogICAgeSAgICAgPSAiQ291bnQiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQojIyAhIFF4eC4xNCBQcm9iYWJpbGl0eSBvZiBoaWdoZXIgdGhhbiAyJSB0YXJnZXQNClRvIGtlZXAgaW5mbGF0aW9uIGxvdyBhbmQgc3RhYmxlLCBHb3Zlcm5tZW50IHNldHMgYW4gaW5mbGF0aW9uIHRhcmdldCBvZiAyJS4gIEJhc2VkIG9uIHRoZSBpbmZsYXRpb24gZm9yZWNhc3QgcHJvdmlkZWQsIHdoYXQgZG8geW91IHRoaW5rIGlzIHRoZSBwcm9iYWJpbGl0eSBvZiBpbmZsYXRpb24gZXhjZWVkaW5nIDIlP1wNCkRlZmluaXRpdmUgQ29ycmVjdCBBbnN3ZXIgLSAzXA0KdmFyaWFibGU6IGNhdGVnb3JpY2FsXA0KTWV0aG9kOiBjb250aW5nZW5jeSB0YWJsZSAmIHByb3BvcnRpb24gdGVzdFwNCioqUmVzdWx0OiBDb250cm9sIGdyb3VwIGlzIHNpZ25pZmljYW50IGRpZmZlcmVudCBmcm9tIGVycm9yIEJhciBncm91cCBhbmQgYmVsbCBjdXJ2ZSBncm91cDsgRXJyb3IgYmFyIGdyb3VwIGhhcyBzaG93biBzdGF0aXN0aWNhbCBkaWZmZXJlbmNlIGNvbXBhcmVkIHRvIGZhbiBjaGFydCBzbGljZS4gNDQlIG9mIHRvdGFsIHJlc3BvbmRlbnRzIGNhbiB1bmRlcnN0YW5kIHRoZSBwcm9iYWJpbGl0eSBvZiBpbmZsYXRpb24gYmVpbmcgaGlnaGVyIHRoYW4gNiUgY29ycmVjdGx5LioqDQpgYGB7cn0NCiMgY29tYmluZSBkYXRhIGZyb20gZGlmZmVyZW50IGdyb3Vwcw0Kc3VydmV5X3ExNCA8LSBkYXRhLmZyYW1lKCkNCnN1cnZleV9xMTRfbGlzdCA8LSBsaXN0KCJRNC4xNCIsIlE2LjE0IiwgIlE4LjE0IiwgIlExMC4xNCIsICJRMTIuMTQiKQ0KZm9yIChpIGluIHNlcV9hbG9uZyhncm91cF9saXN0KSkgew0KICBkZiA8LSBncm91cF9saXN0W1tpXV0NCiAgY29sIDwtIHN1cnZleV9xMTRfbGlzdFtbaV1dDQogIHRlbXBfdGFibGUgPC0gZGZbLCBjKGNvbCwgImdyb3VwIildDQogIG5hbWVzKHRlbXBfdGFibGUpIDwtIGMoInExNF92YWx1ZSIsICJncm91cCIpDQogIHN1cnZleV9xMTQgPC0gcmJpbmQoc3VydmV5X3ExNCwgdGVtcF90YWJsZSkNCn0NCnN1cnZleV9xMTQkcTE0X3ZhbHVlIDwtIGFzLm51bWVyaWMoc3VydmV5X3ExNCRxMTRfdmFsdWUpDQpgYGANClRlc3QgdGhlIHByb3BvcnRpb24gb2YgY29ycmVjdCBhbnN3ZXINCmBgYHtyfQ0Kc3VydmV5X3ExNF9jb250aW5nZW5jeSA8LSB0YWJsZShzdXJ2ZXlfcTE0JHExNF92YWx1ZSwgc3VydmV5X3ExNCRncm91cCkNCiMgcHJpbnQgdGhlIGNvbnRpbmdlbmN5IHRhYmxlDQpwcmludChzdXJ2ZXlfcTE0X2NvbnRpbmdlbmN5KQ0KDQpzdXJ2ZXlfcTE0X2NvcnJlY3QgPC0gc3VydmV5X3ExNF9jb250aW5nZW5jeVszLF0NCnN1cnZleV9xMTRfZ3JvdXBfdG90YWwgPC0gY29sU3VtcyhzdXJ2ZXlfcTE0X2NvbnRpbmdlbmN5KQ0KcHJvcC50ZXN0KHN1cnZleV9xMTRfY29ycmVjdCwgc3VydmV5X3ExNF9ncm91cF90b3RhbCkNCmBgYA0KUGFpcndpc2UgcHJvcG9ydGlvbiB0ZXN0DQpgYGB7cn0NCnBhaXJ3aXNlLnByb3AudGVzdCgNCiAgeCA9IHN1cnZleV9xMTRfY29udGluZ2VuY3lbMywgXSwNCiAgbiA9IGNvbFN1bXMoc3VydmV5X3ExNF9jb250aW5nZW5jeSksDQogIHAuYWRqdXN0Lm1ldGhvZCA9ICJib25mZXJyb25pIiAjIG9yICJob2xtIiwgIkJIIg0KKQ0KYGBgDQpQbG90IHByb2JhYmlsaXR5IG9mIGhpZ2hlciB0aGFuIDIlIHRhcmdldCBwcm9wb3J0aW9uIGJhciBwbG90IGFjcm9zcyBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCnN1cnZleV9xMTRfcHJvcCAgPC0gYXMuZGF0YS5mcmFtZShzdXJ2ZXlfcTE0X2NvbnRpbmdlbmN5KQ0KIyByZW5hbWUgY29sdW1ucw0KbmFtZXMoc3VydmV5X3ExNF9wcm9wKSA8LSBjKCJReHguMTQiLCAiR3JvdXAiLCAiQ291bnQiKQ0KIyBhZGQgYSBsYWJlbGxlZCBjb2x1bW4NCnN1cnZleV9xMTRfcHJvcCA8LSBzdXJ2ZXlfcTE0X3Byb3AgJT4lDQogIG11dGF0ZShReHguMTRfbGFiZWwgPSBjYXNlX3doZW4oDQogICAgUXh4LjE0ID09ICIxIiB+ICIxLT45OSUiLA0KICAgIFF4eC4xNCA9PSAiMiIgfiAiMi1hcm91bmQgODAlIiwNCiAgICBReHguMTQgPT0gIjMiIH4gIjMtYXJvdW5kIDYwJSIsDQogICAgUXh4LjE0ID09ICI0IiB+ICI0LWFyb3VuZCA1MCUiLA0KICAgIFF4eC4xNCA9PSAiNSIgfiAiNS1hcm91bmQgMzAlIiwNCiAgICBReHguMTQgPT0gIjYiIH4gIjYtYXJvdW5kIDIwJSIsDQogICAgUXh4LjE0ID09ICI3IiB+ICI3LTwxJSINCiAgKSkNCiMgY2FsY3VsYXRlIHByb3BvcnRpb25zIHdpdGhpbiBlYWNoIGdyb3VwDQpzdXJ2ZXlfcTE0X3Byb3AgPC0gc3VydmV5X3ExNF9wcm9wICU+JQ0KICBncm91cF9ieShHcm91cCkgJT4lDQogIG11dGF0ZShQcm9wb3J0aW9uID0gQ291bnQgLyBzdW0oQ291bnQpKQ0KDQpnZ3Bsb3Qoc3VydmV5X3ExNF9wcm9wLCBhZXMoeCA9IGFzLmZhY3RvcihgUXh4LjE0X2xhYmVsYCksIHkgPSBQcm9wb3J0aW9uLCBmaWxsID0gR3JvdXApKSArIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICAjIGZhY2V0X3dyYXAofkdyb3VwKSsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJReHguMTQgUHJvYmFiaWxpdHkgb2YgaGlnaGVyIHRoYW4gMiUgdGFyZ2V0IFByb3BvdGlvbiBQbG90IGFjcm9zcyBHcm91cHMiLA0KICAgIHggPSAiUmVzcG9uc2UiLA0KICAgIHkgPSAiUHJvcG9ydGlvbiINCiAgKSArDQogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANClBsb3QgdGhlIGhpc3RvZ3JhbSBpbmNsdWRpbmcgYWxsIHBhcnRpY2lwYW50cw0KYGBge3J9DQojIGhpc3RvZ3JhbSBpbmNsdWRpbmcgYWxsIHBhcnRpY2lwYW50cw0KZ2dwbG90KHN1cnZleV9xMTQsIGFlcyh4ID0gcTE0X3ZhbHVlKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEsIGZpbGwgPSAic3RlZWxibHVlIiwgY29sb3IgPSAid2hpdGUiKSArDQogICMgZmFjZXRfd3JhcCh+IGdyb3VwKSArDQogIGxhYnModGl0bGUgPSAiUXh4LjE0IFByb2JhYmlsaXR5IG9mIGhpZ2hlciB0aGFuIDIlIHRhcmdldCBIaXN0b2dyYW0iLA0KICAgICAgIHggPSAiUXh4LjE0IiwNCiAgICAgICB5ID0gIkNvdW50IikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIG1heChzdXJ2ZXlfcTE0JHExNF92YWx1ZSwgbmEucm0gPSBUUlVFKSwgYnkgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQojIyBReHguMTUgRGV2aWF0aW9uIGZyb20gY2VudHJhbCBlc3RpbWF0ZQ0KQmFzZWQgb24gdGhlIGluZmxhdGlvbiBmb3JlY2FzdCBwcm92aWRlZCwgZG8geW91IHRoaW5rIHRoZXJlIGlzIGEgaGlnaGVyIHJpc2sgb2YgaW5mbGF0aW9uIGluIDIwMjZRMiBleGNlZWRpbmcgdGhlIGNlbnRyYWwgZXN0aW1hdGUgb3Igb2YgYmVpbmcgbGVzcyB0aGFuIHRoaXMgY2VudHJhbCBlc3RpbWF0ZT9cDQpEZWZpbml0aXZlIENvcnJlY3QgQW5zd2VyIC0gM1wNCnZhcmlhYmxlOiBjYXRlZ29yaWNhbFwNCk1ldGhvZDogY29udGluZ2VuY3kgdGFibGUgJiBwcm9wb3J0aW9uIHRlc3RcDQoqKlJlc3VsdDogVGhlIGNvbnRyb2wgZ3JvdXAgc2hvd3Mgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBjb21wYXJlZCB0byB0aGUgc2hhZGVkIGJhciBncm91cCBpbiB0ZXJtcyBvZiB0aGUgY29ycmVjdGx5IGNob29zaW5nIHVuZGVyc3RhbmRpbmcgdGhlIHJpc2sgaXMgZXF1YWwuIEFtb25nIGFsbCBwYXJ0aWNpcGFudHMsIG9ubHkgYXJvdW5kIDglIHJlc3BvbmRlbnRzIHRoaW5rIHRoZXJlIGlzIGRvd25zaWRlIHJpc2suIFRoZSBsYXJnZXN0IHByb3BvcnRpb24gKDQ4JSkgb2YgcGFydGljaXBhbnRzIGJlbGlldmUgdGhlcmUgaXMgdXBzaWRlIHJpc2suICoqDQpgYGB7cn0NCiMgY29tYmluZSBkYXRhIGZyb20gZGlmZmVyZW50IGdyb3Vwcw0Kc3VydmV5X3ExNSA8LSBkYXRhLmZyYW1lKCkNCnN1cnZleV9xMTVfbGlzdCA8LSBsaXN0KCJRNC4xNSIsIlE2LjE1IiwgIlE4LjE1IiwgIlExMC4xNSIsICJRMTIuMTUiKQ0KZm9yIChpIGluIHNlcV9hbG9uZyhncm91cF9saXN0KSkgew0KICBkZiA8LSBncm91cF9saXN0W1tpXV0NCiAgY29sIDwtIHN1cnZleV9xMTVfbGlzdFtbaV1dDQogIHRlbXBfdGFibGUgPC0gZGZbLCBjKGNvbCwgImdyb3VwIildDQogIG5hbWVzKHRlbXBfdGFibGUpIDwtIGMoInExNV92YWx1ZSIsICJncm91cCIpDQogIHN1cnZleV9xMTUgPC0gcmJpbmQoc3VydmV5X3ExNSwgdGVtcF90YWJsZSkNCn0NCnN1cnZleV9xMTUkcTE1X3ZhbHVlIDwtIGFzLm51bWVyaWMoc3VydmV5X3ExNSRxMTVfdmFsdWUpDQpgYGANCg0KQ29udGluZ2VuY3kgdGFibGUNCmBgYHtyfQ0Kc3VydmV5X3ExNV9jb250aW5nZW5jeSA8LSB0YWJsZShzdXJ2ZXlfcTE1JHExNV92YWx1ZSwgc3VydmV5X3ExNSRncm91cCkNCiMgcHJpbnQgdGhlIGNvbnRpbmdlbmN5IHRhYmxlDQpwcmludChzdXJ2ZXlfcTE1X2NvbnRpbmdlbmN5KQ0KIyBjaGktc3F1YXJlZCB0ZXN0DQpjaGlzcV9yZXN1bHQgPC0gY2hpc3EudGVzdChzdXJ2ZXlfcTE1X2NvbnRpbmdlbmN5KQ0Kc3RkX3Jlc2lkIDwtIGNoaXNxX3Jlc3VsdCRzdGRyZXMNCnByaW50KHN0ZF9yZXNpZCkNCg0KIyBjb3JyZWN0IGFuc3dlcg0Kc3VydmV5X3ExNV9jb3JyZWN0IDwtIHN1cnZleV9xMTVfY29udGluZ2VuY3lbMyxdDQpzdXJ2ZXlfcTE1X2dyb3VwX3RvdGFsIDwtIGNvbFN1bXMoc3VydmV5X3ExNV9jb250aW5nZW5jeSkNCnByb3AudGVzdChzdXJ2ZXlfcTE1X2NvcnJlY3QsIHN1cnZleV9xMTVfZ3JvdXBfdG90YWwpDQpgYGANClBhaXJ3aXNlIHByb3BvcnRpb24gdGVzdA0KYGBge3J9DQpwYWlyd2lzZS5wcm9wLnRlc3QoDQogIHggPSBzdXJ2ZXlfcTE1X2NvbnRpbmdlbmN5WzMsIF0sDQogIG4gPSBjb2xTdW1zKHN1cnZleV9xMTVfY29udGluZ2VuY3kpLA0KICBwLmFkanVzdC5tZXRob2QgPSAiYm9uZmVycm9uaSIgIyBvciAiaG9sbSIsICJCSCINCikNCmBgYA0KDQoNClBsb3QgcHJvcG9ydGlvbiBiYXIgcGxvdCBhY3Jvc3MgZGlmZmVyZW50IGdyb3Vwcw0KYGBge3J9DQpzdXJ2ZXlfcTE1X3Byb3AgIDwtIGFzLmRhdGEuZnJhbWUoc3VydmV5X3ExNV9jb250aW5nZW5jeSkNCiMgcmVuYW1lIGNvbHVtbnMNCm5hbWVzKHN1cnZleV9xMTVfcHJvcCkgPC0gYygiUXh4LjE1IiwgIkdyb3VwIiwgIkNvdW50IikNCiMgYWRkIGEgbGFiZWxsZWQgY29sdW1uDQpzdXJ2ZXlfcTE1X3Byb3AgPC0gc3VydmV5X3ExNV9wcm9wICU+JQ0KICBtdXRhdGUoUXh4LjE1X2xhYmVsID0gY2FzZV93aGVuKA0KICAgIFF4eC4xNSA9PSAiMSIgfiAiMS1iaWdnZXIgdXBzaWRlIHJpc2siLA0KICAgIFF4eC4xNSA9PSAiMiIgfiAiMi1iaWdnZXIgZG93bnNpZGUgcmlzayIsDQogICAgUXh4LjE1ID09ICIzIiB+ICIzLWVxdWFsIHJpc2tzIG9uIGJvdGggc2lkZXMiDQogICkpDQojIGNhbGN1bGF0ZSBwcm9wb3J0aW9ucyB3aXRoaW4gZWFjaCBncm91cA0Kc3VydmV5X3ExNV9wcm9wIDwtIHN1cnZleV9xMTVfcHJvcCAlPiUNCiAgZ3JvdXBfYnkoR3JvdXApICU+JQ0KICBtdXRhdGUoUHJvcG9ydGlvbiA9IENvdW50IC8gc3VtKENvdW50KSkNCmdncGxvdChzdXJ2ZXlfcTE1X3Byb3AsIGFlcyh4ID0gYXMuZmFjdG9yKGBReHguMTVfbGFiZWxgKSwgeSA9IFByb3BvcnRpb24sIGZpbGwgPSBHcm91cCkpICsgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogICMgZmFjZXRfd3JhcCh+R3JvdXApKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlF4eC4xNSBBbnN3ZXIgUHJvcG90aW9uIFBsb3QgYWNyb3NzIEdyb3VwcyIsDQogICAgeCA9ICJSZXNwb25zZSIsDQogICAgeSA9ICJQcm9wb3J0aW9uIg0KICApICsNCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KUGxvdCB0aGUgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCiMgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpnZ3Bsb3Qoc3VydmV5X3ExNSwgYWVzKHggPSBxMTVfdmFsdWUpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMSwgZmlsbCA9ICJzdGVlbGJsdWUiLCBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgIyBmYWNldF93cmFwKH4gZ3JvdXApICsNCiAgbGFicyh0aXRsZSA9ICJReHguMTUgQW5zd2VyIEJhciBDaGFydCIsDQogICAgICAgeCA9ICJReHguMTUiLA0KICAgICAgIHkgPSAiQ291bnQiKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgbWF4KHN1cnZleV9xMTUkcTE1X3ZhbHVlLCBuYS5ybSA9IFRSVUUpLCBieSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQojIyBReHguMTcgU2VsZi1yZXBvcnRlZCBsaWtlbGlob29kIG9mIGV4YWN0bHkgMi42JQ0KSG93IGxpa2VseSBkbyB5b3UgdGhpbmsgaXQgaXMgdGhhdCB0aGUgaW5mbGF0aW9uIHdpbGwgYmUgZXhhY3RseSAyLjYlP1wNCiphc2NlbmRpbmcgdmFsdWUtaW5jcmVhc2luZyBsaWtlbGlob29kKlwNClZhcmlhYmxlOiB0cmVhdCBhcyBjb250aW51b3VzXA0KTWV0aG9kOiBLcnVza2FsLVdhbGxpcyB0ZXN0XA0KKipSZXN1bHQ6IEZhaWwgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMuIFRoZSBvdmVyYWxsIGRpc3RyaWJ1dGlvbiBpcyBza2V3ZWQgdG93YXJkcyB1bmxpa2VseS4qKg0KYGBge3J9DQojIGNvbWJpbmUgZGF0YSBmcm9tIGRpZmZlcmVudCBncm91cHMNCnN1cnZleV9xMTcgPC0gZGF0YS5mcmFtZSgpDQpzdXJ2ZXlfcTE3X2xpc3QgPC0gbGlzdCgiUTQuMTdfMSIsIlE2LjE3XzEiLCAiUTguMTdfMSIsICJRMTAuMTdfMSIsICJRMTIuMTdfMSIpDQpmb3IgKGkgaW4gc2VxX2Fsb25nKGdyb3VwX2xpc3QpKSB7DQogIGRmIDwtIGdyb3VwX2xpc3RbW2ldXQ0KICBjb2wgPC0gc3VydmV5X3ExN19saXN0W1tpXV0NCiAgdGVtcF90YWJsZSA8LSBkZlssIGMoY29sLCAiZ3JvdXAiKV0NCiAgbmFtZXModGVtcF90YWJsZSkgPC0gYygicTE3X3ZhbHVlIiwgImdyb3VwIikNCiAgc3VydmV5X3ExNyA8LSByYmluZChzdXJ2ZXlfcTE3LCB0ZW1wX3RhYmxlKQ0KfQ0Kc3VydmV5X3ExNyRxMTdfdmFsdWUgPC0gYXMubnVtZXJpYyhzdXJ2ZXlfcTE3JHExN192YWx1ZSkNCg0KYGBgDQoNCktXIHRlc3QNCmBgYHtyfQ0KIyBjaGVjayBub3JtYWxpdHkgLS0+IHRoZSBkYXRhIGlzIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZA0KIyBzaGFwaXJvLnRlc3Qoc3VydmV5X3ExNyRxMTdfdmFsdWUpDQoNCiMgcnVuIEtydXNrYWwtV2FsbGlzIHRlc3QNCmtydXNrYWxfdGVzdCA8LSBrcnVza2FsLnRlc3QocTE3X3ZhbHVlIH4gZ3JvdXAsIGRhdGEgPSBzdXJ2ZXlfcTE3KQ0KcHJpbnQoa3J1c2thbF90ZXN0KQ0KYGBgDQoNClBsb3QgdGhlIGRpc3RyaWJ1dGlvbiBvZiBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCiMgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpnZ3Bsb3Qoc3VydmV5X3ExNywgYWVzKHggPSBxMTdfdmFsdWUpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMSwgZmlsbCA9ICJzdGVlbGJsdWUiLCBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgIyBmYWNldF93cmFwKH4gZ3JvdXApICsNCiAgbGFicyh0aXRsZSA9ICJReHguMTcgU2VsZi1yZXBvcnRlZCBsaWtlbGlob29kIG9mIGV4YWN0bHkgMi42JSBkaXN0cmlidXRpb24iLA0KICAgICAgIHggPSAiUXh4LjE3IiwNCiAgICAgICB5ID0gIkNvdW50IikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYXMubnVtZXJpYyhuYW1lcyhsaWtlbGlob29kX2xhYmVscykpLCANCiAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGxpa2VsaWhvb2RfbGFiZWxzKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQoNCiMgR3JvdXBlZCBiYXItc3R5bGUgaGlzdG9ncmFtDQpnZ3Bsb3Qoc3VydmV5X3ExNywgYWVzKHggPSBmYWN0b3IocTE3X3ZhbHVlKSwgZmlsbCA9IGZhY3Rvcihncm91cCkpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICAjIGZhY2V0X3dyYXAofiBncm91cCkgKw0KICAjIGFkZCBsYWJlbHMNCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9bGlrZWxpaG9vZF9sYWJlbHMpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJReHguMTcgU2VsZi1yZXBvcnRlZCBsaWtlbGlob29kIG9mIGV4YWN0bHkgMi42JSBkaXN0cmlidXRpb24gYnkgZ3JvdXAiLA0KICAgIHggPSAiUXh4LjE3IFJlc3BvbnNlIiwNCiAgICB5ID0gIkNvdW50IiwNCiAgICBmaWxsID0gIkdyb3VwIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCg0KYGBgDQojIyBReHguMjEgU2VsZi1yZXBvcnRlZCBsaWtlbGlob29kIG9mIGluZmxhdGlvbiBiZWluZyBiZXR3ZWVuIDEuOSUgYW5kIDMuMyUNCkhvdyBsaWtlbHkgZG8geW91IHRoaW5rIGl0IGlzIHRoYXQgdGhlIGluZmxhdGlvbiB3aWxsIGJlIGJldHdlZW4gMS45JSBhbmQgMy4zJT9cDQoqYXNjZW5kaW5nIHZhbHVlLWluY3JlYXNpbmcgbGlrZWxpaG9vZCpcDQpWYXJpYWJsZTogdHJlYXQgYXMgY29udGludW91c1wNCk1ldGhvZDogS3J1c2thbC1XYWxsaXMgdGVzdFwNCioqUmVzdWx0OiBGYWlsIHRvIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzLiBUaGUgbWFqb3JpdHkgb2YgcmVzcG9uZGVudHMgdGhpbmsgaXQncyBxdWl0ZSBsaWtlbHkuKioNCmBgYHtyfQ0KIyBjb21iaW5lIGRhdGEgZnJvbSBkaWZmZXJlbnQgZ3JvdXBzDQpzdXJ2ZXlfcTIxIDwtIGRhdGEuZnJhbWUoKQ0Kc3VydmV5X3EyMV9saXN0IDwtIGxpc3QoIlE0LjIxXzEiLCJRNi4yMV8xIiwgIlE4LjIxXzEiLCAiUTEwLjIxXzEiLCAiUTEyLjIxXzEiKQ0KZm9yIChpIGluIHNlcV9hbG9uZyhncm91cF9saXN0KSkgew0KICBkZiA8LSBncm91cF9saXN0W1tpXV0NCiAgY29sIDwtIHN1cnZleV9xMjFfbGlzdFtbaV1dDQogIHRlbXBfdGFibGUgPC0gZGZbLCBjKGNvbCwgImdyb3VwIildDQogIG5hbWVzKHRlbXBfdGFibGUpIDwtIGMoInEyMV92YWx1ZSIsICJncm91cCIpDQogIHN1cnZleV9xMjEgPC0gcmJpbmQoc3VydmV5X3EyMSwgdGVtcF90YWJsZSkNCn0NCnN1cnZleV9xMjEkcTIxX3ZhbHVlIDwtIGFzLm51bWVyaWMoc3VydmV5X3EyMSRxMjFfdmFsdWUpDQpgYGANCg0KS1cgdGVzdA0KYGBge3J9DQojIGNoZWNrIG5vcm1hbGl0eSAtLT4gdGhlIGRhdGEgaXMgbm90IG5vcm1hbGx5IGRpc3RyaWJ1dGVkDQojIHNoYXBpcm8udGVzdChzdXJ2ZXlfcTIxJHEyMV92YWx1ZSkNCg0KIyBydW4gS3J1c2thbC1XYWxsaXMgdGVzdA0Ka3J1c2thbF90ZXN0IDwtIGtydXNrYWwudGVzdChxMjFfdmFsdWUgfiBncm91cCwgZGF0YSA9IHN1cnZleV9xMjEpDQpwcmludChrcnVza2FsX3Rlc3QpDQpgYGANClBsb3QgdGhlIGRpc3RyaWJ1dGlvbiBvZiBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCiMgR3JvdXBlZCBiYXItc3R5bGUgaGlzdG9ncmFtDQpnZ3Bsb3Qoc3VydmV5X3EyMSwgYWVzKHggPSBmYWN0b3IocTIxX3ZhbHVlKSwgZmlsbCA9IGZhY3Rvcihncm91cCkpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICAjIGZhY2V0X3dyYXAofiBncm91cCkgKw0KICAjIGFkZCBsYWJlbHMNCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9bGlrZWxpaG9vZF9sYWJlbHMpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJReHguMjEgU2VsZi1yZXBvcnRlZCBsaWtlbGlob29kIG9mIGluZmxhdGlvbiBiZWluZyBiZXR3ZWVuIDEuOSUgYW5kIDMuMyUgZGlzdHJpYnV0aW9uIGJ5IGdyb3VwIiwNCiAgICB4ID0gIlF4eC4yMSBSZXNwb25zZSIsDQogICAgeSA9ICJDb3VudCIsDQogICAgZmlsbCA9ICJHcm91cCINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANCg0KUGxvdCBiYXIgY2hhcnQgaW5jbHVkaW5nIGFsbCBwYXJ0aWNpcGFudHMNCmBgYHtyfQ0KIyBoaXN0b2dyYW0gaW5jbHVkaW5nIGFsbCBwYXJ0aWNpcGFudHMNCmdncGxvdChzdXJ2ZXlfcTIxLCBhZXMoeCA9IHEyMV92YWx1ZSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxLCBmaWxsID0gInN0ZWVsYmx1ZSIsIGNvbG9yID0gIndoaXRlIikgKw0KICAjIGZhY2V0X3dyYXAofiBncm91cCkgKw0KICBsYWJzKHRpdGxlID0gIlF4eC4yMSBTZWxmLXJlcG9ydGVkIGxpa2VsaWhvb2Qgb2YgaW5mbGF0aW9uIGJlaW5nIGJldHdlZW4gMS45JSBhbmQgMy4zJSBkaXN0cmlidXRpb24iLA0KICAgICAgIHggPSAiUXh4LjIxIiwNCiAgICAgICB5ID0gIkNvdW50IikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYXMubnVtZXJpYyhuYW1lcyhsaWtlbGlob29kX2xhYmVscykpLCANCiAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGxpa2VsaWhvb2RfbGFiZWxzKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANCiMjICEgUXh4LjIyIFNlbGYtcmVwb3J0ZWQgbGlrZWxpaG9vZCBvZiBpbmZsYXRpb24gYmVpbmcgYmV0d2VlbiAzLjMlIGFuZCA1LjYlDQpIb3cgbGlrZWx5IGRvIHlvdSB0aGluayBpdCBpcyB0aGF0IHRoZSBpbmZsYXRpb24gd2lsbCBiZSBiZXR3ZWVuIDMuMyUgYW5kIDUuNiU/XA0KKmFzY2VuZGluZyB2YWx1ZS1pbmNyZWFzaW5nIGxpa2VsaWhvb2QqXA0KVmFyaWFibGU6IHRyZWF0IGFzIGNvbnRpbnVvdXNcDQpNZXRob2Q6IEtydXNrYWwtV2FsbGlzIHRlc3RcDQoqKlJlc3VsdDogVGhlIGRpc3RyaWJ1dGlvbiBvZiBzaGFkZWQgYmFyIGdyb3VwIGFuZCBiZWxsIGN1cnZlIHNob3cgc3RhdGlzdGljYWwgZGlmZmVyZW5jZS4gTmVhciBoYWxmIG9mIHRoZSByZXNwb25kZW50cyB0aGluayBpdCdzIHF1aXRlIHVubGlrZWx5LioqDQpgYGB7cn0NCiMgY29tYmluZSBkYXRhIGZyb20gZGlmZmVyZW50IGdyb3Vwcw0Kc3VydmV5X3EyMiA8LSBkYXRhLmZyYW1lKCkNCnN1cnZleV9xMjJfbGlzdCA8LSBsaXN0KCJRNC4yMl8xIiwiUTYuMjJfMSIsICJROC4yMl8xIiwgIlExMC4yMl8xIiwgIlExMi4yMl8xIikNCmZvciAoaSBpbiBzZXFfYWxvbmcoZ3JvdXBfbGlzdCkpIHsNCiAgZGYgPC0gZ3JvdXBfbGlzdFtbaV1dDQogIGNvbCA8LSBzdXJ2ZXlfcTIyX2xpc3RbW2ldXQ0KICB0ZW1wX3RhYmxlIDwtIGRmWywgYyhjb2wsICJncm91cCIpXQ0KICBuYW1lcyh0ZW1wX3RhYmxlKSA8LSBjKCJxMjJfdmFsdWUiLCAiZ3JvdXAiKQ0KICBzdXJ2ZXlfcTIyIDwtIHJiaW5kKHN1cnZleV9xMjIsIHRlbXBfdGFibGUpDQp9DQpzdXJ2ZXlfcTIyJHEyMl92YWx1ZSA8LSBhcy5udW1lcmljKHN1cnZleV9xMjIkcTIyX3ZhbHVlKQ0KYGBgDQoNCktXIHRlc3QNCmBgYHtyfQ0KIyBjaGVjayBub3JtYWxpdHkgLS0+IHRoZSBkYXRhIGlzIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZA0KIyBzaGFwaXJvLnRlc3Qoc3VydmV5X3EyMiRxMjJfdmFsdWUpDQoNCiMgcnVuIEtydXNrYWwtV2FsbGlzIHRlc3QNCmtydXNrYWxfdGVzdCA8LSBrcnVza2FsLnRlc3QocTIyX3ZhbHVlIH4gZ3JvdXAsIGRhdGEgPSBzdXJ2ZXlfcTIyKQ0KcHJpbnQoa3J1c2thbF90ZXN0KQ0KDQojIFBvc3QtaG9jIHRlc3QNCmR1bm5UZXN0KHEyMl92YWx1ZSB+IGdyb3VwLCBkYXRhID0gc3VydmV5X3EyMiwgbWV0aG9kID0gImJvbmZlcnJvbmkiKQ0KYGBgDQoNClBsb3QgdGhlIGRpc3RyaWJ1dGlvbiBvZiBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCiMgR3JvdXBlZCBiYXItc3R5bGUgaGlzdG9ncmFtDQpnZ3Bsb3Qoc3VydmV5X3EyMiwgYWVzKHggPSBmYWN0b3IocTIyX3ZhbHVlKSwgZmlsbCA9IGZhY3Rvcihncm91cCkpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICAjIGZhY2V0X3dyYXAofiBncm91cCkgKw0KICAjIGFkZCBsYWJlbHMNCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9bGlrZWxpaG9vZF9sYWJlbHMpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJReHguMjIgU2VsZi1yZXBvcnRlZCBsaWtlbGlob29kIG9mIGluZmxhdGlvbiBiZWluZyBiZXR3ZWVuIDMuMyUgYW5kIDUuNiUgZGlzdHJpYnV0aW9uIGJ5IGdyb3VwIiwNCiAgICB4ID0gIlF4eC4yMiBSZXNwb25zZSIsDQogICAgeSA9ICJDb3VudCIsDQogICAgZmlsbCA9ICJHcm91cCINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANClBsb3QgYmFyIGNoYXJ0IGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCiMgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpnZ3Bsb3Qoc3VydmV5X3EyMiwgYWVzKHggPSBxMjJfdmFsdWUpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMSwgZmlsbCA9ICJzdGVlbGJsdWUiLCBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgIyBmYWNldF93cmFwKH4gZ3JvdXApICsNCiAgbGFicyh0aXRsZSA9ICJReHguMjIgU2VsZi1yZXBvcnRlZCBsaWtlbGlob29kIG9mIGluZmxhdGlvbiBiZWluZyBiZXR3ZWVuIDMuMyUgYW5kIDUuNiUgZGlzdHJpYnV0aW9uIiwNCiAgICAgICB4ID0gIlF4eC4yMiIsDQogICAgICAgeSA9ICJDb3VudCIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLm51bWVyaWMobmFtZXMobGlrZWxpaG9vZF9sYWJlbHMpKSwgDQogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBsaWtlbGlob29kX2xhYmVscykgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQojIyBReHguMjMgU2VsZi1yZXBvcnRlZCBsaWtlbGlob29kIG9mIGluZmxhdGlvbiBiZWluZyBoaWdoZXIgdGhhbiAzJQ0KSG93IGxpa2VseSBkbyB5b3UgdGhpbmsgaXQgaXMgdGhhdCB0aGUgaW5mbGF0aW9uIHdpbGwgYmUgaGlnaGVyIHRoYW4gMyU/XA0KKmFzY2VuZGluZyB2YWx1ZS1pbmNyZWFzaW5nIGxpa2VsaWhvb2QqXA0KVmFyaWFibGU6IHRyZWF0IGFzIGNvbnRpbnVvdXNcDQpNZXRob2Q6IEtydXNrYWwtV2FsbGlzIHRlc3RcDQoqKlJlc3VsdDogRmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcy4gVGhlIG1ham9yaXR5IG9mIHJlc3BvbmRlbnRzIHRoaW5rIGl0J3MgcXVpdGUgdW5saWtlbHksIGJ1dCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlLioqDQpgYGB7cn0NCiMgY29tYmluZSBkYXRhIGZyb20gZGlmZmVyZW50IGdyb3Vwcw0Kc3VydmV5X3EyMyA8LSBkYXRhLmZyYW1lKCkNCnN1cnZleV9xMjNfbGlzdCA8LSBsaXN0KCJRNC4yM18xIiwiUTYuMjNfMSIsICJROC4yM18xIiwgIlExMC4yM18xIiwgIlExMi4yM18xIikNCmZvciAoaSBpbiBzZXFfYWxvbmcoZ3JvdXBfbGlzdCkpIHsNCiAgZGYgPC0gZ3JvdXBfbGlzdFtbaV1dDQogIGNvbCA8LSBzdXJ2ZXlfcTIzX2xpc3RbW2ldXQ0KICB0ZW1wX3RhYmxlIDwtIGRmWywgYyhjb2wsICJncm91cCIpXQ0KICBuYW1lcyh0ZW1wX3RhYmxlKSA8LSBjKCJxMjNfdmFsdWUiLCAiZ3JvdXAiKQ0KICBzdXJ2ZXlfcTIzIDwtIHJiaW5kKHN1cnZleV9xMjMsIHRlbXBfdGFibGUpDQp9DQpzdXJ2ZXlfcTIzJHEyM192YWx1ZSA8LSBhcy5udW1lcmljKHN1cnZleV9xMjMkcTIzX3ZhbHVlKQ0KYGBgDQpLVyB0ZXN0DQpgYGB7cn0NCiMgY2hlY2sgbm9ybWFsaXR5IC0tPiB0aGUgZGF0YSBpcyBub3Qgbm9ybWFsbHkgZGlzdHJpYnV0ZWQNCiMgc2hhcGlyby50ZXN0KHN1cnZleV9xMjMkcTIzX3ZhbHVlKQ0KDQojIHJ1biBLcnVza2FsLVdhbGxpcyB0ZXN0DQprcnVza2FsX3Rlc3QgPC0ga3J1c2thbC50ZXN0KHEyM192YWx1ZSB+IGdyb3VwLCBkYXRhID0gc3VydmV5X3EyMykNCnByaW50KGtydXNrYWxfdGVzdCkNCmBgYA0KUGxvdCB0aGUgZGlzdHJpYnV0aW9uIG9mIGRpZmZlcmVudCBncm91cHMNCmBgYHtyfQ0KIyBHcm91cGVkIGJhci1zdHlsZSBoaXN0b2dyYW0NCmdncGxvdChzdXJ2ZXlfcTIzLCBhZXMoeCA9IGZhY3RvcihxMjNfdmFsdWUpLCBmaWxsID0gZmFjdG9yKGdyb3VwKSkpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogICMgZmFjZXRfd3JhcCh+IGdyb3VwKSArDQogICMgYWRkIGxhYmVscw0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1saWtlbGlob29kX2xhYmVscykgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlF4eC4yMyBTZWxmLXJlcG9ydGVkIGxpa2VsaWhvb2Qgb2YgaW5mbGF0aW9uIGJlaW5nIGhpZ2hlciB0aGFuIDMlIGRpc3RyaWJ1dGlvbiBieSBncm91cCIsDQogICAgeCA9ICJReHguMjMgUmVzcG9uc2UiLA0KICAgIHkgPSAiQ291bnQiLA0KICAgIGZpbGwgPSAiR3JvdXAiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQpQbG90IGJhciBjaGFydCBpbmNsdWRpbmcgYWxsIHBhcnRpY2lwYW50cw0KYGBge3J9DQojIGhpc3RvZ3JhbSBpbmNsdWRpbmcgYWxsIHBhcnRpY2lwYW50cw0KZ2dwbG90KHN1cnZleV9xMjMsIGFlcyh4ID0gcTIzX3ZhbHVlKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEsIGZpbGwgPSAic3RlZWxibHVlIiwgY29sb3IgPSAid2hpdGUiKSArDQogICMgZmFjZXRfd3JhcCh+IGdyb3VwKSArDQogIGxhYnModGl0bGUgPSAiUXh4LjIzIFNlbGYtcmVwb3J0ZWQgbGlrZWxpaG9vZCBvZiBpbmZsYXRpb24gYmVpbmcgaGlnaGVyIHRoYW4gMyUgZGlzdHJpYnV0aW9uIiwNCiAgICAgICB4ID0gIlF4eC4yMyIsDQogICAgICAgeSA9ICJDb3VudCIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLm51bWVyaWMobmFtZXMobGlrZWxpaG9vZF9sYWJlbHMpKSwgDQogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBsaWtlbGlob29kX2xhYmVscykgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQoNCg0KIyMgUXh4LjI2IEFjY3VyYWN5IG9mIGNlbnRyYWwgZXN0aW1hdGUNCk9uIGEgc2NhbGUgb2YgMSB0byAxMCwgd2hlcmUgMSBtZWFucyBub3QgYWNjdXJhdGUgYXQgYWxsIGFuZCAxMCBtZWFucyB2ZXJ5IGFjY3VyYXRlLCBob3cgYWNjdXJhdGUgZG8geW91IHRoaW5rIHRoZSBjZW50cmFsIGVzdGltYXRlIGluIHRoZSBncmFwaCBpcz9cDQoqMS1Ob3QgYWNjdXJhdGUgYXQgYWxsOyAxMC1WZXJ5IGFjY3VyYXRlKlwNClZhcmlhYmxlOiBjb250aW51b3VzXA0KTWV0aG9kOiBBTk5PVkEgdGVzdCBvciBLVyB0ZXN0IChkZXBlbmRzIG9uIHdoZXRoZXIgaXQncyBub3JtYWxseSBkaXN0cmlidXRlZClcDQoqKlJlc3VsdDogRmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcy4qKg0KYGBge3J9DQojIGNvbWJpbmUgZGF0YSBmcm9tIGRpZmZlcmVudCBncm91cHMNCnN1cnZleV9xMjYgPC0gZGF0YS5mcmFtZSgpDQpzdXJ2ZXlfcTI2X2xpc3QgPC0gbGlzdCgiUTQuMjZfMSIsIlE2LjI2XzEiLCAiUTguMjZfMSIsICJRMTAuMjZfMSIsICJRMTIuMjZfMSIpDQpmb3IgKGkgaW4gc2VxX2Fsb25nKGdyb3VwX2xpc3QpKSB7DQogIGRmIDwtIGdyb3VwX2xpc3RbW2ldXQ0KICBjb2wgPC0gc3VydmV5X3EyNl9saXN0W1tpXV0NCiAgdGVtcF90YWJsZSA8LSBkZlssIGMoY29sLCAiZ3JvdXAiKV0NCiAgbmFtZXModGVtcF90YWJsZSkgPC0gYygicTI2X3ZhbHVlIiwgImdyb3VwIikNCiAgc3VydmV5X3EyNiA8LSByYmluZChzdXJ2ZXlfcTI2LCB0ZW1wX3RhYmxlKQ0KfQ0Kc3VydmV5X3EyNiRxMjZfdmFsdWUgPC0gYXMubnVtZXJpYyhzdXJ2ZXlfcTI2JHEyNl92YWx1ZSkNCmBgYA0KU3RhdGlzdGljYWwgdGVzdA0KYGBge3J9DQojIEluaXRpYWwgQ2hlY2sNCiMgc3VtbWFyeShzdXJ2ZXlfcTI2JHEyNl92YWx1ZSkNCg0KIyBjaGVjayBub3JtYWxpdHkgLS0+IHRoZSBkYXRhIGlzIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZA0KIyBzaGFwaXJvLnRlc3Qoc3VydmV5X3EyNiRxMjZfdmFsdWUpDQoNCiMgcnVuIEtydXNrYWwtV2FsbGlzIHRlc3QNCmtydXNrYWxfdGVzdCA8LSBrcnVza2FsLnRlc3QocTI2X3ZhbHVlIH4gZ3JvdXAsIGRhdGEgPSBzdXJ2ZXlfcTI2KQ0KcHJpbnQoa3J1c2thbF90ZXN0KQ0KDQpgYGANClN1bW1hcnkgc3RhdGlzdGljcw0KYGBge3J9DQojIFN1bW1hcnkgc3RhdGlzdGljcw0Kc3VydmV5X3EyNl9zdW1tYXJ5IDwtIHN1cnZleV9xMjYgJT4lDQogIGdyb3VwX2J5KGdyb3VwKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIG1lYW4gPSBtZWFuKHEyNl92YWx1ZSwgbmEucm0gPSBUUlVFKSwNCiAgICBtZWRpYW4gPSBtZWRpYW4ocTI2X3ZhbHVlLCBuYS5ybSA9IFRSVUUpLA0KICAgIHNkID0gc2QocTI2X3ZhbHVlLCBuYS5ybSA9IFRSVUUpDQogICkNCmBgYA0KDQoNClBsb3QgdGhlIGRpc3RyaWJ1dGlvbiBvZiBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCiMgR3JvdXBlZCBiYXItc3R5bGUgaGlzdG9ncmFtXA0KZ2dwbG90KHN1cnZleV9xMjYsIGFlcyh4ID0gZmFjdG9yKHEyNl92YWx1ZSksIGZpbGwgPSBmYWN0b3IoZ3JvdXApKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgIyBmYWNldF93cmFwKH4gZ3JvdXApICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJReHguMjYgQWNjdXJhY3kgb2YgY2VudHJhbCBlc3RpbWF0ZSBkaXN0cmlidXRpb24gYnkgZ3JvdXAiLA0KICAgIHggPSAiUXh4LjI2IFJlc3BvbnNlIiwNCiAgICB5ID0gIkNvdW50IiwNCiAgICBmaWxsID0gIkdyb3VwIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQojIyBReHguMjcgQ2VydGFpbnR5IG9mIGNlbnRyYWwgZXN0aW1hdGUNCk9uIGEgc2NhbGUgb2YgMSB0byAxMCwgd2hlcmUgMSBtZWFucyB2ZXJ5IHVuY2VydGFpbiBhbmQgMTAgbWVhbnMgdmVyeSBjZXJ0YWluLCBob3cgY2VydGFpbiBvciB1bmNlcnRhaW4gZG8geW91IHRoaW5rIHRoZSBpbmZsYXRpb24gZm9yZWNhc3QgZm9yIDIwMjYgUTIgaXM/XA0KKjEtVmVyeSB1bmNlcnRhaW47IDEwLVZlcnkgY2VydGFpbipcDQpWYXJpYWJsZTogY29udGludW91c1wNCk1ldGhvZDogQU5OT1ZBIHRlc3Qgb3IgS1cgdGVzdCAoZGVwZW5kcyBvbiB3aGV0aGVyIGl0J3Mgbm9ybWFsbHkgZGlzdHJpYnV0ZWQpXA0KKipSZXN1bHQ6IEZhaWwgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMuICoqDQpgYGB7cn0NCiMgY29tYmluZSBkYXRhIGZyb20gZGlmZmVyZW50IGdyb3Vwcw0Kc3VydmV5X3EyNyA8LSBkYXRhLmZyYW1lKCkNCnN1cnZleV9xMjdfbGlzdCA8LSBsaXN0KCJRNC4yN18xIiwiUTYuMjdfMSIsICJROC4yN18xIiwgIlExMC4yN18xIiwgIlExMi4yN18xIikNCmZvciAoaSBpbiBzZXFfYWxvbmcoZ3JvdXBfbGlzdCkpIHsNCiAgZGYgPC0gZ3JvdXBfbGlzdFtbaV1dDQogIGNvbCA8LSBzdXJ2ZXlfcTI3X2xpc3RbW2ldXQ0KICB0ZW1wX3RhYmxlIDwtIGRmWywgYyhjb2wsICJncm91cCIpXQ0KICBuYW1lcyh0ZW1wX3RhYmxlKSA8LSBjKCJxMjdfdmFsdWUiLCAiZ3JvdXAiKQ0KICBzdXJ2ZXlfcTI3IDwtIHJiaW5kKHN1cnZleV9xMjcsIHRlbXBfdGFibGUpDQp9DQpzdXJ2ZXlfcTI3JHEyN192YWx1ZSA8LSBhcy5udW1lcmljKHN1cnZleV9xMjckcTI3X3ZhbHVlKQ0KYGBgDQpTdGF0aXN0aWNhbCB0ZXN0DQpgYGB7cn0NCiMgSW5pdGlhbCBDaGVjaw0KIyBzdW1tYXJ5KHN1cnZleV9xMjckcTI3X3ZhbHVlKQ0KIyBjaGVjayBub3JtYWxpdHkgLS0+IHRoZSBkYXRhIGlzIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZA0KIyBzaGFwaXJvLnRlc3Qoc3VydmV5X3EyNyRxMjdfdmFsdWUpDQojIHJ1biBLcnVza2FsLVdhbGxpcyB0ZXN0DQprcnVza2FsX3Rlc3QgPC0ga3J1c2thbC50ZXN0KHEyN192YWx1ZSB+IGdyb3VwLCBkYXRhID0gc3VydmV5X3EyNykNCnByaW50KGtydXNrYWxfdGVzdCkNCmBgYA0KU3VtbWFyeSBzdGF0aXN0aWNzDQpgYGB7cn0NCiMgU3VtbWFyeSBzdGF0aXN0aWNzDQpzdXJ2ZXlfcTI3X3N1bW1hcnkgPC0gc3VydmV5X3EyNyAlPiUNCiAgZ3JvdXBfYnkoZ3JvdXApICU+JQ0KICBzdW1tYXJpc2UoDQogICAgbWVhbiA9IG1lYW4ocTI3X3ZhbHVlLCBuYS5ybSA9IFRSVUUpLA0KICAgIG1lZGlhbiA9IG1lZGlhbihxMjdfdmFsdWUsIG5hLnJtID0gVFJVRSksDQogICAgc2QgPSBzZChxMjdfdmFsdWUsIG5hLnJtID0gVFJVRSkNCiAgKQ0KYGBgDQpQbG90IHRoZSBkaXN0cmlidXRpb24gb2YgZGlmZmVyZW50IGdyb3Vwcw0KYGBge3J9DQojIEdyb3VwZWQgYmFyLXN0eWxlIGhpc3RvZ3JhbQ0KZ2dwbG90KHN1cnZleV9xMjcsIGFlcyh4ID0gZmFjdG9yKHEyN192YWx1ZSksIGZpbGwgPSBmYWN0b3IoZ3JvdXApKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgZmFjZXRfd3JhcCh+IGdyb3VwKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUXh4LjI3IFRoZSBkaXN0cmlidXRpb24gb2YgY2VhcnRhaW50eS91bmNlcnRhaW50eSBvZiB0aGUgY2VudHJhbCBlc3RpbWF0ZSBieSBncm91cCIsDQogICAgeCA9ICJReHguMjcgUmVzcG9uc2UiLA0KICAgIHkgPSAiQ291bnQiLA0KICAgIGZpbGwgPSAiR3JvdXAiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoNCiMjIFF4eC4yOSBSZXByZXNlbnRhdGl2ZW5lc3Mgb2YgdGhlIHVuY2VydGFpbnR5DQpPbiBhIHNjYWxlIG9mIDEgdG8gMTAsIHdoZXJlIDEgbWVhbnMgbm90IHJlcHJlc2VudGF0aXZlIGF0IGFsbCBhbmQgMTAgbWVhbnMgdmVyeSByZXByZXNlbnRhdGl2ZSwgaG93IHJlcHJlc2VudGF0aXZlIGRvIHlvdSB0aGluayB0aGUgdW5jZXJ0YWludHkgYmVpbmcgY29tbXVuaWNhdGVkIGlzIChpLmUuLCBob3cgd2VsbCB0aGUgZ2l2ZW4gaW5mb3JtYXRpb24gcmVmbGVjdHMgdGhlIHRydWUgdmFyaWFiaWxpdHkgb3IgdW5jZXJ0YWludHkgb2YgdGhlIGZvcmVjYXN0PylcDQoqMS1Ob3QgcmVwcmVzZW50YXRpdmUgYXQgYWxsOyAxMC1WZXJ5IHJlcHJlc2VudGF0aXZlKlwNClZhcmlhYmxlOiBjb250aW51b3VzXA0KTWV0aG9kOiBBTk5PVkEgdGVzdCBvciBLVyB0ZXN0IChkZXBlbmRzIG9uIHdoZXRoZXIgaXQncyBub3JtYWxseSBkaXN0cmlidXRlZClcDQoqKlJlc3VsdDogRmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcy4qKg0KYGBge3J9DQojIGNvbWJpbmUgZGF0YSBmcm9tIGRpZmZlcmVudCBncm91cHMNCnN1cnZleV9xMjkgPC0gZGF0YS5mcmFtZSgpDQpzdXJ2ZXlfcTI5X2xpc3QgPC0gbGlzdCgiUTQuMjlfMSIsIlE2LjI5XzEiLCAiUTguMjlfMSIsICJRMTAuMjlfMSIsICJRMTIuMjlfMSIpDQpmb3IgKGkgaW4gc2VxX2Fsb25nKGdyb3VwX2xpc3QpKSB7DQogIGRmIDwtIGdyb3VwX2xpc3RbW2ldXQ0KICBjb2wgPC0gc3VydmV5X3EyOV9saXN0W1tpXV0NCiAgdGVtcF90YWJsZSA8LSBkZlssIGMoY29sLCAiZ3JvdXAiKV0NCiAgbmFtZXModGVtcF90YWJsZSkgPC0gYygicTI5X3ZhbHVlIiwgImdyb3VwIikNCiAgc3VydmV5X3EyOSA8LSByYmluZChzdXJ2ZXlfcTI5LCB0ZW1wX3RhYmxlKQ0KfQ0Kc3VydmV5X3EyOSRxMjlfdmFsdWUgPC0gYXMubnVtZXJpYyhzdXJ2ZXlfcTI5JHEyOV92YWx1ZSkNCmBgYA0KDQpTdGF0aXN0aWNhbCB0ZXN0DQpgYGB7cn0NCiMgSW5pdGlhbCBDaGVjaw0KIyBzdW1tYXJ5KHN1cnZleV9xMjkkcTI5X3ZhbHVlKQ0KIyBjaGVjayBub3JtYWxpdHkgLS0+IHRoZSBkYXRhIGlzIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZA0KIyBzaGFwaXJvLnRlc3Qoc3VydmV5X3EyOSRxMjlfdmFsdWUpDQojIHJ1biBLcnVza2FsLVdhbGxpcyB0ZXN0DQprcnVza2FsX3Rlc3QgPC0ga3J1c2thbC50ZXN0KHEyOV92YWx1ZSB+IGdyb3VwLCBkYXRhID0gc3VydmV5X3EyOSkNCnByaW50KGtydXNrYWxfdGVzdCkNCmBgYA0KU3VtbWFyeSBzdGF0aXN0aWNzDQpgYGB7cn0NCiMgU3VtbWFyeSBzdGF0aXN0aWNzDQpzdXJ2ZXlfcTI5X3N1bW1hcnkgPC0gc3VydmV5X3EyOSAlPiUNCiAgZ3JvdXBfYnkoZ3JvdXApICU+JQ0KICBzdW1tYXJpc2UoDQogICAgbWVhbiA9IG1lYW4ocTI5X3ZhbHVlLCBuYS5ybSA9IFRSVUUpLA0KICAgIG1lZGlhbiA9IG1lZGlhbihxMjlfdmFsdWUsIG5hLnJtID0gVFJVRSksDQogICAgc2QgPSBzZChxMjlfdmFsdWUsIG5hLnJtID0gVFJVRSkNCiAgKQ0KYGBgDQpQbG90IHRoZSBkaXN0cmlidXRpb24gb2YgZGlmZmVyZW50IGdyb3Vwcw0KYGBge3J9DQojIEdyb3VwZWQgYmFyLXN0eWxlIGhpc3RvZ3JhbQ0KZ2dwbG90KHN1cnZleV9xMjksIGFlcyh4ID0gZmFjdG9yKHEyOV92YWx1ZSksIGZpbGwgPSBmYWN0b3IoZ3JvdXApKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgIyBmYWNldF93cmFwKH4gZ3JvdXApICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJReHguMjkgVGhlIGRpc3RyaWJ1dGlvbiBvZiByZXByZXNlbnRhdGl2ZW5lc3Mgb2YgdGhlIHVuY2VydGFpbnR5IGJ5IGdyb3VwIiwNCiAgICB4ID0gIlF4eC4yOSBSZXNwb25zZSIsDQogICAgeSA9ICJDb3VudCIsDQogICAgZmlsbCA9ICJHcm91cCINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCiMjICEgUXh4LjMwIFJlYWRhYmlsaXR5IG9mIHRoZSBGb3JlY2FzdA0KT24gYSBzY2FsZSBvZiAxIHRvIDEwLCB3aGVyZSAxIG1lYW5zIHZlcnkgZGlmZmljdWx0IGFuZCAxMCBtZWFucyB2ZXJ5IGVhc3ksIGhvdyBlYXN5IG9yIGRpZmZpY3VsdCBkbyB5b3UgZmluZCB0aGUgZ3JhcGggdG8gdW5kZXJzdGFuZD9cDQoqMS1WZXJ5IGRpZmZpY3VsdDsgMTAtVmVyeSBlYXN5KlwNClZhcmlhYmxlOiBjb250aW51b3VzXA0KTWV0aG9kOiBBTk5PVkEgdGVzdCBvciBLVyB0ZXN0IChkZXBlbmRzIG9uIHdoZXRoZXIgaXQncyBub3JtYWxseSBkaXN0cmlidXRlZClcDQoqKlJlc3VsdDogRmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcy4gVGhlcmUgYXJlIHN0YXRpc3RpY2FsIGRpZmZlcmVuY2UgYmV0d2VlbiBjb250cm9sIGdyb3VwIHZzLiBmYW4gY2hhcnQgc2xpY2UgZ3JvdXA7IGNvbnRyb2wgZ3JvdXAgdnMuIGJlbGwgY3VydmU7IGVycm9yIGJhciBncm91cCB2cy4gYmVsbCBjdXJ2ZSBncm91cC4qKg0KYGBge3J9DQojIGNvbWJpbmUgZGF0YSBmcm9tIGRpZmZlcmVudCBncm91cHMNCnN1cnZleV9xMzAgPC0gZGF0YS5mcmFtZSgpDQpzdXJ2ZXlfcTMwX2xpc3QgPC0gbGlzdCgiUTQuMzBfMSIsIlE2LjMwXzEiLCAiUTguMzBfMSIsICJRMTAuMzBfMSIsICJRMTIuMzBfMSIpDQpmb3IgKGkgaW4gc2VxX2Fsb25nKGdyb3VwX2xpc3QpKSB7DQogIGRmIDwtIGdyb3VwX2xpc3RbW2ldXQ0KICBjb2wgPC0gc3VydmV5X3EzMF9saXN0W1tpXV0NCiAgdGVtcF90YWJsZSA8LSBkZlssIGMoY29sLCAiZ3JvdXAiKV0NCiAgbmFtZXModGVtcF90YWJsZSkgPC0gYygicTMwX3ZhbHVlIiwgImdyb3VwIikNCiAgc3VydmV5X3EzMCA8LSByYmluZChzdXJ2ZXlfcTMwLCB0ZW1wX3RhYmxlKQ0KfQ0Kc3VydmV5X3EzMCRxMzBfdmFsdWUgPC0gYXMubnVtZXJpYyhzdXJ2ZXlfcTMwJHEzMF92YWx1ZSkNCmBgYA0KDQpTdGF0aXN0aWNhbCB0ZXN0DQpgYGB7cn0NCiMgSW5pdGlhbCBDaGVjaw0KIyBzdW1tYXJ5KHN1cnZleV9xMzAkcTMwX3ZhbHVlKQ0KIyBjaGVjayBub3JtYWxpdHkgLS0+IHRoZSBkYXRhIGlzIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZA0KIyBzaGFwaXJvLnRlc3Qoc3VydmV5X3EzMCRxMzBfdmFsdWUpDQojIHJ1biBLcnVza2FsLVdhbGxpcyB0ZXN0DQprcnVza2FsX3Rlc3QgPC0ga3J1c2thbC50ZXN0KHEzMF92YWx1ZSB+IGdyb3VwLCBkYXRhID0gc3VydmV5X3EzMCkNCnByaW50KGtydXNrYWxfdGVzdCkNCiMgUG9zdC1ob2MgdGVzdA0KZHVublRlc3QocTMwX3ZhbHVlIH4gZ3JvdXAsIGRhdGEgPSBzdXJ2ZXlfcTMwLCBtZXRob2QgPSAiYm9uZmVycm9uaSIpDQpgYGANClN1bW1hcnkgc3RhdGlzdGljcw0KYGBge3J9DQojIFN1bW1hcnkgc3RhdGlzdGljcw0Kc3VydmV5X3EzMF9zdW1tYXJ5IDwtIHN1cnZleV9xMzAgJT4lDQogIGdyb3VwX2J5KGdyb3VwKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIG1lYW4gPSBtZWFuKHEzMF92YWx1ZSwgbmEucm0gPSBUUlVFKSwNCiAgICBtZWRpYW4gPSBtZWRpYW4ocTMwX3ZhbHVlLCBuYS5ybSA9IFRSVUUpLA0KICAgIHNkID0gc2QocTMwX3ZhbHVlLCBuYS5ybSA9IFRSVUUpDQogICkNCmBgYA0KDQpQbG90IHRoZSBkaXN0cmlidXRpb24gb2YgZGlmZmVyZW50IGdyb3Vwcw0KYGBge3J9DQojIEdyb3VwZWQgYmFyLXN0eWxlIGhpc3RvZ3JhbQ0KZ2dwbG90KHN1cnZleV9xMzAsIGFlcyh4ID0gZmFjdG9yKHEzMF92YWx1ZSksIGZpbGwgPSBmYWN0b3IoZ3JvdXApKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgIyBmYWNldF93cmFwKH4gZ3JvdXApICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJReHguMzAgVGhlIGRpc3RyaWJ1dGlvbiBvZiByZWFkYWJpbGl0eSBvZiB0aGUgZm9yZWNhc3QgYnkgZ3JvdXAiLA0KICAgIHggPSAiUXh4LjMwIFJlc3BvbnNlIiwNCiAgICB5ID0gIkNvdW50IiwNCiAgICBmaWxsID0gIkdyb3VwIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCiMjIFF4eC4zMSBUcnVzdCBvZiB0aGUgRm9yZWNhc3QNCk9uIGEgc2NhbGUgb2YgMSB0byAxMCwgd2hlcmUgMSBtZWFucyB5b3UgZG9u4oCZdCB0cnVzdCB0aGUgaW5mbGF0aW9uIGZvcmVjYXN0IGF0IGFsbCBhbmQgMTAgbWVhbnMgeW91IGZ1bGx5IHRydXN0IGl0LCBob3cgbXVjaCBkbyB5b3UgdHJ1c3QgdGhlIGluZmxhdGlvbiBmb3JlY2FzdCBzaG93biBpbiB0aGUgZ3JhcGg/XA0KKjEtRG9uJ3QgdHJ1c3QgYXQgYWxsOyAxMC1GdWxseSB0cnVzdCpcDQpWYXJpYWJsZTogY29udGludW91c1wNCk1ldGhvZDogQU5OT1ZBIHRlc3Qgb3IgS1cgdGVzdCAoZGVwZW5kcyBvbiB3aGV0aGVyIGl0J3Mgbm9ybWFsbHkgZGlzdHJpYnV0ZWQpXA0KKipSZXN1bHQ6IEZhaWwgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMuICoqDQpgYGB7cn0NCiMgY29tYmluZSBkYXRhIGZyb20gZGlmZmVyZW50IGdyb3Vwcw0Kc3VydmV5X3EzMSA8LSBkYXRhLmZyYW1lKCkNCnN1cnZleV9xMzFfbGlzdCA8LSBsaXN0KCJRNC4zMV8xIiwiUTYuMzFfMSIsICJROC4zMV8xIiwgIlExMC4zMV8xIiwgIlExMi4zMV8xIikNCmZvciAoaSBpbiBzZXFfYWxvbmcoZ3JvdXBfbGlzdCkpIHsNCiAgZGYgPC0gZ3JvdXBfbGlzdFtbaV1dDQogIGNvbCA8LSBzdXJ2ZXlfcTMxX2xpc3RbW2ldXQ0KICB0ZW1wX3RhYmxlIDwtIGRmWywgYyhjb2wsICJncm91cCIpXQ0KICBuYW1lcyh0ZW1wX3RhYmxlKSA8LSBjKCJxMzFfdmFsdWUiLCAiZ3JvdXAiKQ0KICBzdXJ2ZXlfcTMxIDwtIHJiaW5kKHN1cnZleV9xMzEsIHRlbXBfdGFibGUpDQp9DQpzdXJ2ZXlfcTMxJHEzMV92YWx1ZSA8LSBhcy5udW1lcmljKHN1cnZleV9xMzEkcTMxX3ZhbHVlKQ0KYGBgDQoNClN0YXRpc3RpY2FsIHRlc3QNCmBgYHtyfQ0KIyBJbml0aWFsIENoZWNrDQojIHN1bW1hcnkoc3VydmV5X3EzMSRxMzFfdmFsdWUpDQoNCiMgY2hlY2sgbm9ybWFsaXR5IC0tPiB0aGUgZGF0YSBpcyBub3Qgbm9ybWFsbHkgZGlzdHJpYnV0ZWQNCiMgc2hhcGlyby50ZXN0KHN1cnZleV9xMzEkcTMxX3ZhbHVlKQ0KDQojIHJ1biBLcnVza2FsLVdhbGxpcyB0ZXN0DQprcnVza2FsX3Rlc3QgPC0ga3J1c2thbC50ZXN0KHEzMV92YWx1ZSB+IGdyb3VwLCBkYXRhID0gc3VydmV5X3EzMSkNCnByaW50KGtydXNrYWxfdGVzdCkNCmBgYA0KU3VtbWFyeSBzdGF0aXN0aWNzDQpgYGB7cn0NCiMgU3VtbWFyeSBzdGF0aXN0aWNzDQpzdXJ2ZXlfcTMxX3N1bW1hcnkgPC0gc3VydmV5X3EzMSAlPiUNCiAgZ3JvdXBfYnkoZ3JvdXApICU+JQ0KICBzdW1tYXJpc2UoDQogICAgbWVhbiA9IG1lYW4ocTMxX3ZhbHVlLCBuYS5ybSA9IFRSVUUpLA0KICAgIG1lZGlhbiA9IG1lZGlhbihxMzFfdmFsdWUsIG5hLnJtID0gVFJVRSksDQogICAgc2QgPSBzZChxMzFfdmFsdWUsIG5hLnJtID0gVFJVRSkNCiAgKQ0KYGBgDQoNClBsb3QgdGhlIGRpc3RyaWJ1dGlvbiBvZiBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCiMgR3JvdXBlZCBiYXItc3R5bGUgaGlzdG9ncmFtDQpnZ3Bsb3Qoc3VydmV5X3EzMSwgYWVzKHggPSBmYWN0b3IocTMxX3ZhbHVlKSwgZmlsbCA9IGZhY3Rvcihncm91cCkpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICAjIGZhY2V0X3dyYXAofiBncm91cCkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlF4eC4zMSBUaGUgZGlzdHJpYnV0aW9uIG9mIHRydXN0IG9mIHRoZSBmb3JlY2FzdCBieSBncm91cCIsDQogICAgeCA9ICJReHguMzEgUmVzcG9uc2UiLA0KICAgIHkgPSAiQ291bnQiLA0KICAgIGZpbGwgPSAiR3JvdXAiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KIyBTa2V3ZWQgRGF0YSA8YSBuYW1lPSJza2V3ZWQtZGF0YSI+PC9hPg0KIyMgUXh4LjMzIFByb2JhYmlsaXR5IG9mIGhpZ2hlciB0aGFuIDMlDQpCYXNlZCBvbiB0aGUgaW5mbGF0aW9uIGZvcmVjYXN0IHByb3ZpZGVkLCB3aGF0IGRvIHlvdSB0aGluayBpcyB0aGUgcHJvYmFiaWxpdHkgb2YgaW5mbGF0aW9uIGVuZGluZyB1cCBoaWdoZXIgdGhhbiAzJT9cDQpEZWZpbml0aXZlIENvcnJlY3QgQW5zd2VyIC0gNVwNClZhcmlhYmxlOiBjYXRlZ29yaWNhbFwNCk1ldGhvZDogY29udGluZ2VuY3kgdGFibGUgJiBwcm9wb3J0aW9uIHRlc3RcDQoqKlJlc3VsdDogVGhlcmUgaXMgbm8gc3RhdGlzdGljYWwgZGlmZmVyZW5jZSBhY3Jvc3MgZGlmZmVyZW50IGdyb3VwcyBhbmQgdGhlIGxhcmdlc3QgcHJvcG9ydGlvbiBvZiBwYXJ0aWNpcGFudHMgY2FuIHVuZGVyc3RhbmQgdGhlIHByb2JhYmlsaXR5IGNvcnJlY3RseSwgYnV0IG9ubHkgYWNjb3VudCBmb3IgMjglIG9mIHRoZSBlbnRpcmUgcmVzcG9uZGVudHMuICoqDQpgYGB7cn0NCiMgY29tYmluZSBkYXRhIGZyb20gZGlmZmVyZW50IGdyb3Vwcw0Kc3VydmV5X3EzMyA8LSBkYXRhLmZyYW1lKCkNCnN1cnZleV9xMzNfbGlzdCA8LSBsaXN0KCJRNi4zMyIsIlE4LjMzIiwgIlExMC4zMyIsICJRMTIuMzMiKQ0KZm9yIChpIGluIHNlcV9hbG9uZyhza2V3ZWRfZ3JvdXBfbGlzdCkpIHsNCiAgZGYgPC0gc2tld2VkX2dyb3VwX2xpc3RbW2ldXQ0KICBjb2wgPC0gc3VydmV5X3EzM19saXN0W1tpXV0NCiAgdGVtcF90YWJsZSA8LSBkZlssIGMoY29sLCAiZ3JvdXAiKV0NCiAgbmFtZXModGVtcF90YWJsZSkgPC0gYygicTMzX3ZhbHVlIiwgImdyb3VwIikNCiAgc3VydmV5X3EzMyA8LSByYmluZChzdXJ2ZXlfcTMzLCB0ZW1wX3RhYmxlKQ0KfQ0Kc3VydmV5X3EzMyRxMzNfdmFsdWUgPC0gYXMubnVtZXJpYyhzdXJ2ZXlfcTMzJHEzM192YWx1ZSkNCmBgYA0KDQpUZXN0IHRoZSBwcm9wb3J0aW9uIG9mIGNvcnJlY3QgYW5zd2VyDQpgYGB7cn0NCnN1cnZleV9xMzNfY29udGluZ2VuY3kgPC0gdGFibGUoc3VydmV5X3EzMyRxMzNfdmFsdWUsIHN1cnZleV9xMzMkZ3JvdXApDQpwcmludChzdXJ2ZXlfcTMzX2NvbnRpbmdlbmN5KQ0Kc3VydmV5X3EzM19jb3JyZWN0IDwtIHN1cnZleV9xMzNfY29udGluZ2VuY3lbNSxdDQpzdXJ2ZXlfcTMzX2dyb3VwX3RvdGFsIDwtIGNvbFN1bXMoc3VydmV5X3EzM19jb250aW5nZW5jeSkNCnByb3AudGVzdChzdXJ2ZXlfcTMzX2NvcnJlY3QsIHN1cnZleV9xMzNfZ3JvdXBfdG90YWwpDQpgYGANClBsb3QgcHJvYmFiaWxpdHkgb2YgaGlnaGVyIHRoYW4gMyUgKHByb3BvcnRpb24gYmFyIHBsb3QgYWNyb3NzIGRpZmZlcmVudCBncm91cHMpDQpgYGB7cn0NCnN1cnZleV9xMzNfcHJvcCAgPC0gYXMuZGF0YS5mcmFtZShzdXJ2ZXlfcTMzX2NvbnRpbmdlbmN5KQ0KIyByZW5hbWUgY29sdW1ucw0KbmFtZXMoc3VydmV5X3EzM19wcm9wKSA8LSBjKCJReHguMzMiLCAiR3JvdXAiLCAiQ291bnQiKQ0KIyBhZGQgYSBsYWJlbGxlZCBjb2x1bW4NCnN1cnZleV9xMzNfcHJvcCA8LSBzdXJ2ZXlfcTMzX3Byb3AgJT4lDQogIG11dGF0ZShReHguMzNfbGFiZWwgPSBjYXNlX3doZW4oDQogICAgUXh4LjMzID09ICIxIiB+ICIxLU1vcmUgdGhhbiA2MCUiLA0KICAgIFF4eC4zMyA9PSAiMiIgfiAiMy00MC01MCUiLA0KICAgIFF4eC4zMyA9PSAiMyIgfiAiNC0zMC00MCUiLA0KICAgIFF4eC4zMyA9PSAiNCIgfiAiNS1MZXNzIHRoYW4gMzAlIiwNCiAgICBReHguMzMgPT0gIjUiIH4gIjItNTAtNjAlIg0KICApKQ0KIyBjYWxjdWxhdGUgcHJvcG9ydGlvbnMgd2l0aGluIGVhY2ggZ3JvdXANCnN1cnZleV9xMzNfcHJvcCA8LSBzdXJ2ZXlfcTMzX3Byb3AgJT4lDQogIGdyb3VwX2J5KEdyb3VwKSAlPiUNCiAgbXV0YXRlKFByb3BvcnRpb24gPSBDb3VudCAvIHN1bShDb3VudCkpDQpnZ3Bsb3Qoc3VydmV5X3EzM19wcm9wLCBhZXMoeCA9IGFzLmZhY3RvcihgUXh4LjMzX2xhYmVsYCksIHkgPSBQcm9wb3J0aW9uLCBmaWxsID0gR3JvdXApKSArIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICAjIGZhY2V0X3dyYXAofkdyb3VwKSsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJReHguMzMgQW5zd2VyIFByb3BvdGlvbiBQbG90IGFjcm9zcyBHcm91cHMiLA0KICAgIHggPSAiUmVzcG9uc2UiLA0KICAgIHkgPSAiUHJvcG9ydGlvbiINCiAgKSArDQogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANClBsb3QgdGhlIGhpc3RvZ3JhbSBpbmNsdWRpbmcgYWxsIHBhcnRpY2lwYW50cw0KYGBge3J9DQojIGZvcmNlIG9yZGVyIGZvciBncmFwaA0Kc3VydmV5X3EzMyA8LSBzdXJ2ZXlfcTMzICU+JQ0KICBtdXRhdGUoDQogICAgcTMzX3ZhbHVlX3JlID0gZmFjdG9yKA0KICAgICAgcTMzX3ZhbHVlLA0KICAgICAgbGV2ZWxzID0gYygxLCA1LCAyLCAzLCA0KQ0KICAgICkNCiAgKQ0KIyBoaXN0b2dyYW0gaW5jbHVkaW5nIGFsbCBwYXJ0aWNpcGFudHMNCmdncGxvdChzdXJ2ZXlfcTMzLCBhZXMoeCA9IHEzM192YWx1ZV9yZSkpICsNCiAgZ2VvbV9iYXIoZmlsbCA9ICJzdGVlbGJsdWUiLCBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJReHguMzMgUmVzcG9uc2VzIChmb3JjZWQgMS01LTItMy00IG9yZGVyKSIsDQogICAgeCAgICAgPSAiUXh4LjMzIiwNCiAgICB5ICAgICA9ICJDb3VudCINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpgYGANCiMjIFF4eC4zNCBTZWxmLXJlcG9ydGVkIGxpa2VsaWhvb2Qgb2YgaW5mbGF0aW9uIGJlaW5nIGhpZ2hlciB0aGFuIDMlDQpIb3cgbGlrZWx5IGRvIHlvdSB0aGluayBpdCBpcyB0aGF0IHRoZSBpbmZsYXRpb24gd2lsbCBiZSBoaWdoZXIgdGhhbiAzJT9cDQoqYXNjZW5kaW5nIHZhbHVlLWluY3JlYXNpbmcgbGlrZWxpaG9vZCpcDQpWYXJpYWJsZTogdHJlYXQgYXMgY29udGludW91c1wNCk1ldGhvZDogS3J1c2thbC1XYWxsaXMgdGVzdFwNCioqUmVzdWx0OiBGYWlsIHRvIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzLiBUaGUgbWFqb3JpdHkgb2YgcmVzcG9uZGVudHMgdGhpbmsgaXQncyBxdWl0ZSBsaWtlbHkuKioNCmBgYHtyfQ0KIyBjb21iaW5lIGRhdGEgZnJvbSBkaWZmZXJlbnQgZ3JvdXBzDQpzdXJ2ZXlfcTM0IDwtIGRhdGEuZnJhbWUoKQ0Kc3VydmV5X3EzNF9saXN0IDwtIGxpc3QoIlE2LjM0XzEiLCJROC4zNF8xIiwgIlExMC4zNF8xIiwgIlExMi4zNF8xIikNCmZvciAoaSBpbiBzZXFfYWxvbmcoc2tld2VkX2dyb3VwX2xpc3QpKSB7DQogIGRmIDwtIHNrZXdlZF9ncm91cF9saXN0W1tpXV0NCiAgY29sIDwtIHN1cnZleV9xMzRfbGlzdFtbaV1dDQogIHRlbXBfdGFibGUgPC0gZGZbLCBjKGNvbCwgImdyb3VwIildDQogIG5hbWVzKHRlbXBfdGFibGUpIDwtIGMoInEzNF92YWx1ZSIsICJncm91cCIpDQogIHN1cnZleV9xMzQgPC0gcmJpbmQoc3VydmV5X3EzNCwgdGVtcF90YWJsZSkNCn0NCnN1cnZleV9xMzQkcTM0X3ZhbHVlIDwtIGFzLm51bWVyaWMoc3VydmV5X3EzNCRxMzRfdmFsdWUpDQpgYGANCktXIHRlc3QNCmBgYHtyfQ0KIyBjaGVjayBub3JtYWxpdHkgLS0+IHRoZSBkYXRhIGlzIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZA0KIyBzaGFwaXJvLnRlc3Qoc3VydmV5X3EzNCRxMzRfdmFsdWUpDQoNCiMgcnVuIEtydXNrYWwtV2FsbGlzIHRlc3QNCmtydXNrYWxfdGVzdCA8LSBrcnVza2FsLnRlc3QocTM0X3ZhbHVlIH4gZ3JvdXAsIGRhdGEgPSBzdXJ2ZXlfcTM0KQ0KcHJpbnQoa3J1c2thbF90ZXN0KQ0KYGBgDQpQbG90IHRoZSBkaXN0cmlidXRpb24gb2YgZGlmZmVyZW50IGdyb3Vwcw0KYGBge3J9DQojIEdyb3VwZWQgYmFyLXN0eWxlIGhpc3RvZ3JhbQ0KZ2dwbG90KHN1cnZleV9xMzQsIGFlcyh4ID0gZmFjdG9yKHEzNF92YWx1ZSksIGZpbGwgPSBmYWN0b3IoZ3JvdXApKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgIyBmYWNldF93cmFwKH4gZ3JvdXApICsNCiAgIyBhZGQgbGFiZWxzDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWxpa2VsaWhvb2RfbGFiZWxzKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUXh4LjM0IFNlbGYtcmVwb3J0ZWQgbGlrZWxpaG9vZCBvZiBpbmZsYXRpb24gYmVpbmcgaGlnaGVyIHRoYW4gMyUgZGlzdHJpYnV0aW9uIGJ5IGdyb3VwIiwNCiAgICB4ID0gIlF4eC4zNCBSZXNwb25zZSIsDQogICAgeSA9ICJDb3VudCIsDQogICAgZmlsbCA9ICJHcm91cCINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANClBsb3QgYmFyIGNoYXJ0IGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCiMgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpnZ3Bsb3Qoc3VydmV5X3EzNCwgYWVzKHggPSBxMzRfdmFsdWUpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMSwgZmlsbCA9ICJzdGVlbGJsdWUiLCBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgIyBmYWNldF93cmFwKH4gZ3JvdXApICsNCiAgbGFicyh0aXRsZSA9ICJReHguMzQgU2VsZi1yZXBvcnRlZCBsaWtlbGlob29kIG9mIGluZmxhdGlvbiBiZWluZyBoaWdoZXIgdGhhbiAzJSBkaXN0cmlidXRpb24iLA0KICAgICAgIHggPSAiUXh4LjM0IiwNCiAgICAgICB5ID0gIkNvdW50IikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYXMubnVtZXJpYyhuYW1lcyhsaWtlbGlob29kX2xhYmVscykpLCANCiAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGxpa2VsaWhvb2RfbGFiZWxzKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANCiMjIFF4eC4zNiBEZXZpYXRpb24gZnJvbSBjZW50cmFsIGVzdGltYXRlDQpCYXNlZCBvbiB0aGUgaW5mbGF0aW9uIGZvcmVjYXN0IHByb3ZpZGVkLCAgZG8geW91IHRoaW5rIHRoZXJlIGlzIGEgaGlnaGVyIHJpc2sgb2YgaW5mbGF0aW9uIGV4Y2VlZGluZyB0aGUgY2VudHJhbCBlc3RpbWF0ZSBvciBvZiBiZWluZyBsZXNzIHRoYW4gdGhpcyBjZW50cmFsIGVzdGltYXRlP1wNCkRlZmluaXRpdmUgQ29ycmVjdCBBbnN3ZXIgLSAxXA0KVmFyaWFibGU6IGNhdGVnb3JpY2FsXA0KTWV0aG9kOiBjb250aW5nZW5jeSB0YWJsZSAmIHByb3BvcnRpb24gdGVzdFwNCioqUmVzdWx0OiBUaGVyZSBpcyBubyBzdGF0aXN0aWNhbCBkaWZmZXJlbmNlIGFjcm9zcyBncm91cC4gNjglIG9mIHJlc3BvbmRlbnRzIGNhbiB1bmRlcnN0YW5kIHRoZXJlIGlzIGJpZ2dlciB1cHNpZGUgcmlzay4gKioNCmBgYHtyfQ0KIyBjb21iaW5lIGRhdGEgZnJvbSBkaWZmZXJlbnQgZ3JvdXBzDQpzdXJ2ZXlfcTM2IDwtIGRhdGEuZnJhbWUoKQ0Kc3VydmV5X3EzNl9saXN0IDwtIGxpc3QoIlE2LjM2IiwiUTguMzYiLCAiUTEwLjM2IiwgIlExMi4zNiIpDQpmb3IgKGkgaW4gc2VxX2Fsb25nKHNrZXdlZF9ncm91cF9saXN0KSkgew0KICBkZiA8LSBza2V3ZWRfZ3JvdXBfbGlzdFtbaV1dDQogIGNvbCA8LSBzdXJ2ZXlfcTM2X2xpc3RbW2ldXQ0KICB0ZW1wX3RhYmxlIDwtIGRmWywgYyhjb2wsICJncm91cCIpXQ0KICBuYW1lcyh0ZW1wX3RhYmxlKSA8LSBjKCJxMzZfdmFsdWUiLCAiZ3JvdXAiKQ0KICBzdXJ2ZXlfcTM2IDwtIHJiaW5kKHN1cnZleV9xMzYsIHRlbXBfdGFibGUpDQp9DQpzdXJ2ZXlfcTM2JHEzNl92YWx1ZSA8LSBhcy5udW1lcmljKHN1cnZleV9xMzYkcTM2X3ZhbHVlKQ0KYGBgDQoNCkNvbnRpbmdlbmN5IHRhYmxlDQpgYGB7cn0NCnN1cnZleV9xMzZfY29udGluZ2VuY3kgPC0gdGFibGUoc3VydmV5X3EzNiRxMzZfdmFsdWUsIHN1cnZleV9xMzYkZ3JvdXApDQpwcmludChzdXJ2ZXlfcTM2X2NvbnRpbmdlbmN5KQ0KY2hpc3FfcmVzdWx0IDwtIGNoaXNxLnRlc3Qoc3VydmV5X3EzNl9jb250aW5nZW5jeSkNCnByaW50KGNoaXNxX3Jlc3VsdCkNCmBgYA0KVGVzdCB0aGUgcHJvcG9ydGlvbiBvZiBjb3JyZWN0IGFuc3dlcg0KYGBge3J9DQpzdXJ2ZXlfcTM2X2NvcnJlY3QgPC0gc3VydmV5X3EzNl9jb250aW5nZW5jeVsxLF0NCnN1cnZleV9xMzZfZ3JvdXBfdG90YWwgPC0gY29sU3VtcyhzdXJ2ZXlfcTM2X2NvbnRpbmdlbmN5KQ0KcHJvcC50ZXN0KHN1cnZleV9xMzZfY29ycmVjdCwgc3VydmV5X3EzNl9ncm91cF90b3RhbCkNCmBgYA0KDQpQbG90IHByb3BvcnRpb24gYmFyIHBsb3QgYWNyb3NzIGRpZmZlcmVudCBncm91cHMNCmBgYHtyfQ0Kc3VydmV5X3EzNl9wcm9wICA8LSBhcy5kYXRhLmZyYW1lKHN1cnZleV9xMzZfY29udGluZ2VuY3kpDQojIHJlbmFtZSBjb2x1bW5zDQpuYW1lcyhzdXJ2ZXlfcTM2X3Byb3ApIDwtIGMoIlF4eC4zNiIsICJHcm91cCIsICJDb3VudCIpDQojIGFkZCBhIGxhYmVsbGVkIGNvbHVtbg0Kc3VydmV5X3EzNl9wcm9wIDwtIHN1cnZleV9xMzZfcHJvcCAlPiUNCiAgbXV0YXRlKFF4eC4zNl9sYWJlbCA9IGNhc2Vfd2hlbigNCiAgICBReHguMzYgPT0gIjEiIH4gIjEtYmlnZ2VyIHVwc2lkZSByaXNrIiwNCiAgICBReHguMzYgPT0gIjIiIH4gIjItYmlnZ2VyIGRvd25zaWRlIHJpc2siLA0KICAgIFF4eC4zNiA9PSAiMyIgfiAiMy1lcXVhbCByaXNrcyBvbiBib3RoIHNpZGVzIg0KICApKQ0KIyBjYWxjdWxhdGUgcHJvcG9ydGlvbnMgd2l0aGluIGVhY2ggZ3JvdXANCnN1cnZleV9xMzZfcHJvcCA8LSBzdXJ2ZXlfcTM2X3Byb3AgJT4lDQogIGdyb3VwX2J5KEdyb3VwKSAlPiUNCiAgbXV0YXRlKFByb3BvcnRpb24gPSBDb3VudCAvIHN1bShDb3VudCkpDQpnZ3Bsb3Qoc3VydmV5X3EzNl9wcm9wLCBhZXMoeCA9IGFzLmZhY3RvcihgUXh4LjM2X2xhYmVsYCksIHkgPSBQcm9wb3J0aW9uLCBmaWxsID0gR3JvdXApKSArIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICAjIGZhY2V0X3dyYXAofkdyb3VwKSsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJReHguMzYgQW5zd2VyIFByb3BvdGlvbiBQbG90IGFjcm9zcyBHcm91cHMiLA0KICAgIHggPSAiUmVzcG9uc2UiLA0KICAgIHkgPSAiUHJvcG9ydGlvbiINCiAgKSArDQogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANCg0KUGxvdCB0aGUgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCiMgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpnZ3Bsb3Qoc3VydmV5X3EzNiwgYWVzKHggPSBxMzZfdmFsdWUpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMSwgZmlsbCA9ICJzdGVlbGJsdWUiLCBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgIyBmYWNldF93cmFwKH4gZ3JvdXApICsNCiAgbGFicyh0aXRsZSA9ICJReHguMzYgQW5zd2VyIEJhciBDaGFydCIsDQogICAgICAgeCA9ICJReHguMzYiLA0KICAgICAgIHkgPSAiQ291bnQiKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgbWF4KHN1cnZleV9xMzYkcTM2X3ZhbHVlLCBuYS5ybSA9IFRSVUUpLCBieSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCiMjID8gUXh4LjM3IFJpc2sgb2YgZW5kaW5nIG91dHNpZGUNCklmIHRoZSBhY3R1YWwgaW5mbGF0aW9uIGVuZHMgdXAgb3V0c2lkZSB0aGUgYmxhY2sgbGluZSwgd2hpY2ggc2lkZSBpcyBtb3JlIGxpa2VseSwgYmFzZWQgb24gdGhlIHVuY2VydGFpbnR5IGRlcGljdGVkIGluIHRoZSBncmFwaD9cDQpEZWZpbml0aXZlIENvcnJlY3QgQW5zd2VyIC0gMVwNClZhcmlhYmxlOiBjYXRlZ29yaWNhbFwNCk1ldGhvZDogY29udGluZ2VuY3kgdGFibGUgJiBwcm9wb3J0aW9uIHRlc3RcDQoqKlJlc3VsdDogNjMlIHJlc3BvbmRlbnRzIHRoaW5rIGlmIHRoZSBhY3R1YWwgaW5mbGF0aW9uIGVuZHMgdXAgb3V0c2lkZSwgaXQncyBtb3JlIGxpa2VseSB0byBiZSBvbiB0aGUgdXBwZXIgc2lkZS4gKioNCmBgYHtyfQ0KIyBjb21iaW5lIGRhdGEgZnJvbSBkaWZmZXJlbnQgZ3JvdXBzDQpzdXJ2ZXlfcTM3IDwtIGRhdGEuZnJhbWUoKQ0Kc3VydmV5X3EzN19saXN0IDwtIGxpc3QoIlE2LjM3IiwiUTguMzciLCAiUTEwLjM3IiwgIlExMi4zNyIpDQpmb3IgKGkgaW4gc2VxX2Fsb25nKHNrZXdlZF9ncm91cF9saXN0KSkgew0KICBkZiA8LSBza2V3ZWRfZ3JvdXBfbGlzdFtbaV1dDQogIGNvbCA8LSBzdXJ2ZXlfcTM3X2xpc3RbW2ldXQ0KICB0ZW1wX3RhYmxlIDwtIGRmWywgYyhjb2wsICJncm91cCIpXQ0KICBuYW1lcyh0ZW1wX3RhYmxlKSA8LSBjKCJxMzdfdmFsdWUiLCAiZ3JvdXAiKQ0KICBzdXJ2ZXlfcTM3IDwtIHJiaW5kKHN1cnZleV9xMzcsIHRlbXBfdGFibGUpDQp9DQpzdXJ2ZXlfcTM3JHEzN192YWx1ZSA8LSBhcy5udW1lcmljKHN1cnZleV9xMzckcTM3X3ZhbHVlKQ0KYGBgDQoNCkNvbnRpbmdlbmN5IHRhYmxlDQpgYGB7cn0NCnN1cnZleV9xMzdfY29udGluZ2VuY3kgPC0gdGFibGUoc3VydmV5X3EzNyRxMzdfdmFsdWUsIHN1cnZleV9xMzckZ3JvdXApDQpwcmludChzdXJ2ZXlfcTM3X2NvbnRpbmdlbmN5KQ0KDQojIGNoaXNxX3Jlc3VsdCA8LSBjaGlzcS50ZXN0KHN1cnZleV9xMzdfY29udGluZ2VuY3kpDQojIHByaW50KGNoaXNxX3Jlc3VsdCkNCg0KIyBUZXN0IHRoZSBwcm9wb3J0aW9uIG9mIGNvcnJlY3QgYW5zd2VyDQpzdXJ2ZXlfcTM3X2NvcnJlY3QgPC0gc3VydmV5X3EzN19jb250aW5nZW5jeVsxLF0NCnN1cnZleV9xMzdfZ3JvdXBfdG90YWwgPC0gY29sU3VtcyhzdXJ2ZXlfcTM3X2NvbnRpbmdlbmN5KQ0KcHJvcC50ZXN0KHN1cnZleV9xMzdfY29ycmVjdCwgc3VydmV5X3EzN19ncm91cF90b3RhbCkNCg0KIyBwYWlyd2lzZSBwcm9wb3J0aW9uIHRlc3QNCnBhaXJ3aXNlLnByb3AudGVzdCgNCiAgeCA9IHN1cnZleV9xMzdfY29udGluZ2VuY3lbMSxdLA0KICBuID0gY29sU3VtcyhzdXJ2ZXlfcTM3X2NvbnRpbmdlbmN5KSwNCiAgcC5hZGp1c3QubWV0aG9kID0gImJvbmZlcnJvbmkiICMgb3IgImhvbG0iLCAiQkgiDQopDQpgYGANClBsb3QgcHJvcG9ydGlvbiBiYXIgcGxvdCBhY3Jvc3MgZGlmZmVyZW50IGdyb3Vwcw0KYGBge3J9DQpzdXJ2ZXlfcTM3X3Byb3AgIDwtIGFzLmRhdGEuZnJhbWUoc3VydmV5X3EzN19jb250aW5nZW5jeSkNCiMgcmVuYW1lIGNvbHVtbnMNCm5hbWVzKHN1cnZleV9xMzdfcHJvcCkgPC0gYygiUXh4LjM3IiwgIkdyb3VwIiwgIkNvdW50IikNCiMgYWRkIGEgbGFiZWxsZWQgY29sdW1uDQpzdXJ2ZXlfcTM3X3Byb3AgPC0gc3VydmV5X3EzN19wcm9wICU+JQ0KICBtdXRhdGUoUXh4LjM3X2xhYmVsID0gY2FzZV93aGVuKA0KICAgIFF4eC4zNyA9PSAiMSIgfiAiMS1Nb3JlIGxpa2VseSB0byBiZSBvbiB0aGUgdXBwZXIgc2lkZSIsDQogICAgUXh4LjM3ID09ICIyIiB+ICIyLU1vcmUgbGlrZWx5IHRvIGJlIG9uIHRoZSBsb3dlciBzaWRlIiwNCiAgICBReHguMzcgPT0gIjMiIH4gIjMtRXF1YWwgY2hhbmNlcyBvZiBiZWluZyBvbiBlaXRoZXIgc2lkZSINCiAgKSkNCiMgY2FsY3VsYXRlIHByb3BvcnRpb25zIHdpdGhpbiBlYWNoIGdyb3VwDQpzdXJ2ZXlfcTM3X3Byb3AgPC0gc3VydmV5X3EzN19wcm9wICU+JQ0KICBncm91cF9ieShHcm91cCkgJT4lDQogIG11dGF0ZShQcm9wb3J0aW9uID0gQ291bnQgLyBzdW0oQ291bnQpKQ0KZ2dwbG90KHN1cnZleV9xMzdfcHJvcCwgYWVzKHggPSBhcy5mYWN0b3IoYFF4eC4zN19sYWJlbGApLCB5ID0gUHJvcG9ydGlvbiwgZmlsbCA9IEdyb3VwKSkgKyBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgIyBmYWNldF93cmFwKH5Hcm91cCkrDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUXh4LjM3IEFuc3dlciBQcm9wb3Rpb24gUGxvdCBhY3Jvc3MgR3JvdXBzIiwNCiAgICB4ID0gIlJlc3BvbnNlIiwNCiAgICB5ID0gIlByb3BvcnRpb24iDQogICkgKw0KICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIikrDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQpQbG90IHRoZSBoaXN0b2dyYW0gaW5jbHVkaW5nIGFsbCBwYXJ0aWNpcGFudHMNCmBgYHtyfQ0KIyBoaXN0b2dyYW0gaW5jbHVkaW5nIGFsbCBwYXJ0aWNpcGFudHMNCmdncGxvdChzdXJ2ZXlfcTM3LCBhZXMoeCA9IHEzN192YWx1ZSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxLCBmaWxsID0gInN0ZWVsYmx1ZSIsIGNvbG9yID0gIndoaXRlIikgKw0KICAjIGZhY2V0X3dyYXAofiBncm91cCkgKw0KICBsYWJzKHRpdGxlID0gIlF4eC4zNyBBbnN3ZXIgQmFyIENoYXJ0IiwNCiAgICAgICB4ID0gIlF4eC4zNyIsDQogICAgICAgeSA9ICJDb3VudCIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCBtYXgoc3VydmV5X3EzNyRxMzdfdmFsdWUsIG5hLnJtID0gVFJVRSksIGJ5ID0gMSkpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KDQoNCg0KIyBEZWNpc2lvbi1tYWtpbmcgPGEgbmFtZT0iZGVjaXNpb24tbWFraW5nIj48L2E+DQojIyBELjMgSW52ZXN0bWVudCBEZWNpc2lvbg0KV2hpY2ggYm9uZCB3b3VsZCB5b3UgY2hvb3NlIHRvIGludmVzdCBpbj9cDQpWYXJpYWJsZTogY2F0ZWdvcmljYWxcDQpNZXRob2Q6IGNvbnRpbmdlbmN5IHRhYmxlICYgcHJvcG9ydGlvbiB0ZXN0XA0KKipSZXN1bHQ6IEZhaWwgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMuICoqDQpgYGB7cn0NCiMgY29tYmluZSBkYXRhIGZyb20gZGlmZmVyZW50IGdyb3Vwcw0Kc3VydmV5X2QzIDwtIGRhdGEuZnJhbWUoKQ0Kc3VydmV5X2QzX2xpc3QgPC0gbGlzdCgiUTUuMyIsIlE3LjMiLCAiUTkuMyIsICJRMTEuMyIsICJRMTMuMyIpDQpmb3IgKGkgaW4gc2VxX2Fsb25nKGdyb3VwX2xpc3QpKSB7DQogIGRmIDwtIGdyb3VwX2xpc3RbW2ldXQ0KICBjb2wgPC0gc3VydmV5X2QzX2xpc3RbW2ldXQ0KICB0ZW1wX3RhYmxlIDwtIGRmWywgYyhjb2wsICJncm91cCIpXQ0KICBuYW1lcyh0ZW1wX3RhYmxlKSA8LSBjKCJkM192YWx1ZSIsICJncm91cCIpDQogIHN1cnZleV9kMyA8LSByYmluZChzdXJ2ZXlfZDMsIHRlbXBfdGFibGUpDQp9DQpzdXJ2ZXlfZDMkZDNfdmFsdWUgPC0gYXMubnVtZXJpYyhzdXJ2ZXlfZDMkZDNfdmFsdWUpDQpgYGANCkNvbnRpbmdlbmN5IHRhYmxlDQpgYGB7cn0NCnN1cnZleV9kM19jb250aW5nZW5jeSA8LSB0YWJsZShzdXJ2ZXlfZDMkZDNfdmFsdWUsIHN1cnZleV9kMyRncm91cCkNCnByaW50KHN1cnZleV9kM19jb250aW5nZW5jeSkNCiMgY2hpLXNxdWFyZWQgdGVzdA0KY2hpc3EudGVzdChzdXJ2ZXlfZDNfY29udGluZ2VuY3kpDQoNCmBgYA0KUGxvdCBwcm9wb3J0aW9uIGJhciBwbG90IGFjcm9zcyBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCnN1cnZleV9kM19wcm9wICA8LSBhcy5kYXRhLmZyYW1lKHN1cnZleV9kM19jb250aW5nZW5jeSkNCiMgcmVuYW1lIGNvbHVtbnMNCm5hbWVzKHN1cnZleV9kM19wcm9wKSA8LSBjKCJELjMiLCAiR3JvdXAiLCAiQ291bnQiKQ0KIyBhZGQgYSBsYWJlbGxlZCBjb2x1bW4NCnN1cnZleV9kM19wcm9wIDwtIHN1cnZleV9kM19wcm9wICU+JQ0KICBtdXRhdGUoRC4zX2xhYmVsID0gY2FzZV93aGVuKA0KICAgIEQuMyA9PSAiMSIgfiAiQS4gTm9taW5hbCBCb25kIiwNCiAgICBELjMgPT0gIjIiIH4gIkIuIEluZmxhdGlvbi1Qcm90ZWN0ZWQgQm9uZCINCiAgKSkNCiMgY2FsY3VsYXRlIHByb3BvcnRpb25zIHdpdGhpbiBlYWNoIGdyb3VwDQpzdXJ2ZXlfZDNfcHJvcCA8LSBzdXJ2ZXlfZDNfcHJvcCAlPiUNCiAgZ3JvdXBfYnkoR3JvdXApICU+JQ0KICBtdXRhdGUoUHJvcG9ydGlvbiA9IENvdW50IC8gc3VtKENvdW50KSkNCmdncGxvdChzdXJ2ZXlfZDNfcHJvcCwgYWVzKHggPSBhcy5mYWN0b3IoYEQuM19sYWJlbGApLCB5ID0gUHJvcG9ydGlvbiwgZmlsbCA9IEdyb3VwKSkgKyBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgIyBmYWNldF93cmFwKH5Hcm91cCkrDQogIGxhYnMoDQogICAgdGl0bGUgPSAiRC4zIEFuc3dlciBQcm9wb3Rpb24gUGxvdCBhY3Jvc3MgR3JvdXBzIiwNCiAgICB4ID0gIlJlc3BvbnNlIiwNCiAgICB5ID0gIlByb3BvcnRpb24iDQogICkgKw0KICAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIikrDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQpQbG90IHBpZSBjaGFydCBpbmNsdWRpbmcgYWxsIHBhcnRpY2lwYW50cw0KYGBge3J9DQpzdXJ2ZXlfZDNfc3VtbWFyeSA8LSBzdXJ2ZXlfZDNfcHJvcCAlPiUNCiAgZ3JvdXBfYnkoYEQuM19sYWJlbGApICU+JQ0KICBzdW1tYXJpc2UodG90YWxfY291bnQgPSBzdW0oQ291bnQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSB0b3RhbF9jb3VudCAvIHN1bSh0b3RhbF9jb3VudCksDQogICAgICAgICBgRC4zX2dyYXBoX2xhYmVsYCA9IHBhc3RlMChgRC4zX2xhYmVsYCwgIiAoIiwgcm91bmQocHJvcG9ydGlvbiAqIDEwMCwgMiksICIgJSkiKSkNCmdncGxvdChzdXJ2ZXlfZDNfc3VtbWFyeSwgYWVzKHggPSAiIix5ID0gcHJvcG9ydGlvbiwgZmlsbCA9IGBELjNfZ3JhcGhfbGFiZWxgKSkgKw0KICBnZW9tX2NvbCh3aWR0aCA9IDEpICsNCiAgY29vcmRfcG9sYXIodGhldGEgPSAieSIpICsNCiAgbGFicyh0aXRsZSA9ICJELjMgSW52ZXN0bWVudCBEZWNpc2lvbiBTdW1tYXJ5IFBpZSBDaGFydCIsDQogICAgICAgeCA9ICIiLA0KICAgICAgIHkgPSAiIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSkNCmBgYA0KIyMgRC40IENvbmZpZGVuY2UgaW4gZGVjaXNpb24tbWFraW5nDQpPbiBhIHNjYWxlIG9mIDEgdG8gMTAsIHdoZXJlIDEgbWVhbnMgbm90IGNvbmZpZGVudCBhdCBhbGwgYW5kIDEwIG1lYW5zIHZlcnkgY29uZmlkZW50LCBob3cgY29uZmlkZW50ICBhcmUgeW91IGluIG1ha2luZyB0aGUgZGVjaXNpb24/XA0KKjEtTm90IGNvbmZpZGVudCBhdCBhbGw7IDEwLVZlcnkgY29uZmlkZW50KlwNClZhcmlhYmxlOiBjb250aW51b3VzXA0KTWV0aG9kOiBBTk5PVkEgdGVzdCBvciBLVyB0ZXN0IChkZXBlbmRzIG9uIHdoZXRoZXIgaXQncyBub3JtYWxseSBkaXN0cmlidXRlZClcDQoqKlJlc3VsdDogRmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcy4gKioNCmBgYHtyfQ0KIyBjb21iaW5lIGRhdGEgZnJvbSBkaWZmZXJlbnQgZ3JvdXBzDQpzdXJ2ZXlfZDQgPC0gZGF0YS5mcmFtZSgpDQpzdXJ2ZXlfZDRfbGlzdCA8LSBsaXN0KCJRNS40XzEiLCJRNy40XzEiLCAiUTkuNF8xIiwgIlExMS40XzEiLCAiUTEzLjRfMSIpDQpmb3IgKGkgaW4gc2VxX2Fsb25nKGdyb3VwX2xpc3QpKSB7DQogIGRmIDwtIGdyb3VwX2xpc3RbW2ldXQ0KICBjb2wgPC0gc3VydmV5X2Q0X2xpc3RbW2ldXQ0KICB0ZW1wX3RhYmxlIDwtIGRmWywgYyhjb2wsICJncm91cCIpXQ0KICBuYW1lcyh0ZW1wX3RhYmxlKSA8LSBjKCJkNF92YWx1ZSIsICJncm91cCIpDQogIHN1cnZleV9kNCA8LSByYmluZChzdXJ2ZXlfZDQsIHRlbXBfdGFibGUpDQp9DQpzdXJ2ZXlfZDQkZDRfdmFsdWUgPC0gYXMubnVtZXJpYyhzdXJ2ZXlfZDQkZDRfdmFsdWUpDQpgYGANClN0YXRpc3RpY2FsIHRlc3QNCmBgYHtyfQ0KIyBJbml0aWFsIENoZWNrDQojIHN1bW1hcnkoc3VydmV5X2Q0JGQ0X3ZhbHVlKQ0KIyBjaGVjayBub3JtYWxpdHkgLS0+IHRoZSBkYXRhIGlzIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZA0KIyBzaGFwaXJvLnRlc3Qoc3VydmV5X2Q0JGQ0X3ZhbHVlKQ0KDQojIHJ1biBLcnVza2FsLVdhbGxpcyB0ZXN0DQprcnVza2FsX3Rlc3QgPC0ga3J1c2thbC50ZXN0KGQ0X3ZhbHVlIH4gZ3JvdXAsIGRhdGEgPSBzdXJ2ZXlfZDQpDQpwcmludChrcnVza2FsX3Rlc3QpDQpgYGANClN1bW1hcnkgc3RhdGlzdGljcw0KYGBge3J9DQojIFN1bW1hcnkgc3RhdGlzdGljcw0Kc3VydmV5X2Q0X3N1bW1hcnkgPC0gc3VydmV5X2Q0ICU+JQ0KICBncm91cF9ieShncm91cCkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBtZWFuID0gbWVhbihkNF92YWx1ZSwgbmEucm0gPSBUUlVFKSwNCiAgICBtZWRpYW4gPSBtZWRpYW4oZDRfdmFsdWUsIG5hLnJtID0gVFJVRSksDQogICAgc2QgPSBzZChkNF92YWx1ZSwgbmEucm0gPSBUUlVFKQ0KICApDQpgYGANClBsb3QgdGhlIGRpc3RyaWJ1dGlvbiBvZiBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCiMgR3JvdXBlZCBiYXItc3R5bGUgaGlzdG9ncmFtDQpnZ3Bsb3Qoc3VydmV5X2Q0LCBhZXMoeCA9IGZhY3RvcihkNF92YWx1ZSksIGZpbGwgPSBmYWN0b3IoZ3JvdXApKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgIyBmYWNldF93cmFwKH4gZ3JvdXApICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJELjQgVGhlIGRpc3RyaWJ1dGlvbiBvZiBjb25maWRlbmNlIGluIGRlY2lzaW9uLW1ha2luZyBieSBncm91cCIsDQogICAgeCA9ICJELjQgUmVzcG9uc2UiLA0KICAgIHkgPSAiQ291bnQiLA0KICAgIGZpbGwgPSAiR3JvdXAiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KIyMgRC42IENvbnNpZGVyaW5nIG5vbWluYWwgYm9uZA0KSWYgdGhlIHByb2JhYmlsaXR5IG9mIGluZmxhdGlvbiBiZWluZyBsb3cgKOKJpCAzJSkgaXMgZ3JlYXRlciB0aGFuIHRoZSBmb2xsb3dpbmcgcGVyY2VudGFnZXMsIEkgd291bGQgY29uc2lkZXIgaW52ZXN0aW5nIGluIHRoZSBub21pbmFsIGJvbmQ6XA0KVmFyaWFibGU6IGNhdGVnb3JpY2FsXA0KTWV0aG9kOiBjb250aW5nZW5jeSB0YWJsZSAmIGNoaS1zcXVhcmVkIHRlc3RcDQoqKlJlc3VsdDogRmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcy4qKg0KYGBge3J9DQojIGNvbWJpbmUgZGF0YSBmcm9tIGRpZmZlcmVudCBncm91cHMNCnN1cnZleV9kNiA8LSBkYXRhLmZyYW1lKCkNCnN1cnZleV9kNl9saXN0IDwtIGxpc3QoIlE1LjYiLCJRNy42IiwgIlE5LjYiLCAiUTExLjYiLCAiUTEzLjYiKQ0KZm9yIChpIGluIHNlcV9hbG9uZyhncm91cF9saXN0KSkgew0KICBkZiA8LSBncm91cF9saXN0W1tpXV0NCiAgY29sIDwtIHN1cnZleV9kNl9saXN0W1tpXV0NCiAgdGVtcF90YWJsZSA8LSBkZlssIGMoY29sLCAiZ3JvdXAiKV0NCiAgbmFtZXModGVtcF90YWJsZSkgPC0gYygiZDZfdmFsdWUiLCAiZ3JvdXAiKQ0KICBzdXJ2ZXlfZDYgPC0gcmJpbmQoc3VydmV5X2Q2LCB0ZW1wX3RhYmxlKQ0KfQ0Kc3VydmV5X2Q2JGQ2X3ZhbHVlIDwtIGFzLm51bWVyaWMoc3VydmV5X2Q2JGQ2X3ZhbHVlKQ0KYGBgDQpDb250aW5nZW5jeSB0YWJsZQ0KYGBge3J9DQpzdXJ2ZXlfZDZfY29udGluZ2VuY3kgPC0gdGFibGUoc3VydmV5X2Q2JGQ2X3ZhbHVlLCBzdXJ2ZXlfZDYkZ3JvdXApDQpwcmludChzdXJ2ZXlfZDZfY29udGluZ2VuY3kpDQojIHJ1biBjaGktc3F1YXJlZCB0ZXN0DQpjaGlzcV9yZXN1bHQgPC0gY2hpc3EudGVzdChzdXJ2ZXlfZDZfY29udGluZ2VuY3kpDQpwcmludChjaGlzcV9yZXN1bHQpDQpgYGANClBsb3QgcHJvcG9ydGlvbiBiYXIgcGxvdCBhY3Jvc3MgZGlmZmVyZW50IGdyb3Vwcw0KYGBge3J9DQpzdXJ2ZXlfZDZfcHJvcCAgPC0gYXMuZGF0YS5mcmFtZShzdXJ2ZXlfZDZfY29udGluZ2VuY3kpDQojIHJlbmFtZSBjb2x1bW5zDQpuYW1lcyhzdXJ2ZXlfZDZfcHJvcCkgPC0gYygiRC42IiwgIkdyb3VwIiwgIkNvdW50IikNCiMgYWRkIGEgbGFiZWxsZWQgY29sdW1uDQpzdXJ2ZXlfZDZfcHJvcCA8LSBzdXJ2ZXlfZDZfcHJvcCAlPiUNCiAgbXV0YXRlKEQuNl9sYWJlbCA9IGNhc2Vfd2hlbigNCiAgICBELjYgPT0gIjEiIH4gIjEtNDAlIiwNCiAgICBELjYgPT0gIjIiIH4gIjItNTAlIiwNCiAgICBELjYgPT0gIjMiIH4gIjMtNjAlIiwNCiAgICBELjYgPT0gIjQiIH4gIjQtZG8gbm90IHRoaW5rIGFib3V0IHByb2JhYmlsaXR5IiwNCiAgICBELjYgPT0gIjUiIH4gIjUtYWx3YXlzIGNob29zZSBhbiBpbmZsYXRpb24tcHJvdGVjdGVkIGJvbmQiLA0KICAgIEQuNiA9PSAiNyIgfiAiNi03MCUiLA0KICAgIEQuNiA9PSAiOCIgfiAiNy04MCUiDQogICkpDQojIGNhbGN1bGF0ZSBwcm9wb3J0aW9ucyB3aXRoaW4gZWFjaCBncm91cA0Kc3VydmV5X2Q2X3Byb3AgPC0gc3VydmV5X2Q2X3Byb3AgJT4lDQogIGdyb3VwX2J5KEdyb3VwKSAlPiUNCiAgbXV0YXRlKFByb3BvcnRpb24gPSBDb3VudCAvIHN1bShDb3VudCkpDQpnZ3Bsb3Qoc3VydmV5X2Q2X3Byb3AsIGFlcyh4ID0gYXMuZmFjdG9yKGBELjZfbGFiZWxgKSwgeSA9IFByb3BvcnRpb24sIGZpbGwgPSBHcm91cCkpICsgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogICMgZmFjZXRfd3JhcCh+R3JvdXApKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkQuNiBBbnN3ZXIgUHJvcG90aW9uIFBsb3QgYWNyb3NzIEdyb3VwcyIsDQogICAgeCA9ICJSZXNwb25zZSIsDQogICAgeSA9ICJQcm9wb3J0aW9uIg0KICApICsNCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KUGxvdCB0aGUgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCiMgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpnZ3Bsb3Qoc3VydmV5X2Q2LCBhZXMoeCA9IGQ2X3ZhbHVlKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEsIGZpbGwgPSAic3RlZWxibHVlIiwgY29sb3IgPSAid2hpdGUiKSArDQogICMgZmFjZXRfd3JhcCh+IGdyb3VwKSArDQogIGxhYnModGl0bGUgPSAiRC42IEhpc3RvZ3JhbSIsDQogICAgICAgeCA9ICJELjYiLA0KICAgICAgIHkgPSAiQ291bnQiKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgbWF4KHN1cnZleV9kNiRkNl92YWx1ZSwgbmEucm0gPSBUUlVFKSwgYnkgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KIyMgRC43IENvbnNpZGVyaW5nIGluZmxhdGlvbi1wcm90ZWN0ZWQgYm9uZA0KSWYgdGhlIHByb2JhYmlsaXR5IG9mIGluZmxhdGlvbiBiZWluZyBoaWdoICg+IDMlKSBpcyBncmVhdGVyIHRoYW4gdGhlIGZvbGxvd2luZyBwZXJjZW50YWdlcywgSSB3b3VsZCBjb25zaWRlciBpbnZlc3RpbmcgaW4gdGhlIGluZmxhdGlvbi1wcm90ZWN0ZWQgYm9uZDpcDQpWYXJpYWJsZTogY2F0ZWdvcmljYWxcDQpNZXRob2Q6IGNvbnRpbmdlbmN5IHRhYmxlICYgY2hpLXNxdWFyZWQgdGVzdFwNCipSZXN1bHQ6IEZhaWwgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMuKioNCmBgYHtyfQ0KIyBjb21iaW5lIGRhdGEgZnJvbSBkaWZmZXJlbnQgZ3JvdXBzDQpzdXJ2ZXlfZDcgPC0gZGF0YS5mcmFtZSgpDQpzdXJ2ZXlfZDdfbGlzdCA8LSBsaXN0KCJRNS43IiwiUTcuNyIsICJROS43IiwgIlExMS43IiwgIlExMy43IikNCmZvciAoaSBpbiBzZXFfYWxvbmcoZ3JvdXBfbGlzdCkpIHsNCiAgZGYgPC0gZ3JvdXBfbGlzdFtbaV1dDQogIGNvbCA8LSBzdXJ2ZXlfZDdfbGlzdFtbaV1dDQogIHRlbXBfdGFibGUgPC0gZGZbLCBjKGNvbCwgImdyb3VwIildDQogIG5hbWVzKHRlbXBfdGFibGUpIDwtIGMoImQ3X3ZhbHVlIiwgImdyb3VwIikNCiAgc3VydmV5X2Q3IDwtIHJiaW5kKHN1cnZleV9kNywgdGVtcF90YWJsZSkNCn0NCnN1cnZleV9kNyRkN192YWx1ZSA8LSBhcy5udW1lcmljKHN1cnZleV9kNyRkN192YWx1ZSkNCmBgYA0KQ29udGluZ2VuY3kgdGFibGUNCmBgYHtyfQ0Kc3VydmV5X2Q3X2NvbnRpbmdlbmN5IDwtIHRhYmxlKHN1cnZleV9kNyRkN192YWx1ZSwgc3VydmV5X2Q3JGdyb3VwKQ0KcHJpbnQoc3VydmV5X2Q3X2NvbnRpbmdlbmN5KQ0KIyBydW4gY2hpLXNxdWFyZWQgdGVzdA0KY2hpc3FfcmVzdWx0IDwtIGNoaXNxLnRlc3Qoc3VydmV5X2Q3X2NvbnRpbmdlbmN5KQ0KcHJpbnQoY2hpc3FfcmVzdWx0KQ0KYGBgDQpQbG90IHByb3BvcnRpb24gYmFyIHBsb3QgYWNyb3NzIGRpZmZlcmVudCBncm91cHMNCmBgYHtyfQ0Kc3VydmV5X2Q3X3Byb3AgIDwtIGFzLmRhdGEuZnJhbWUoc3VydmV5X2Q3X2NvbnRpbmdlbmN5KQ0KIyByZW5hbWUgY29sdW1ucw0KbmFtZXMoc3VydmV5X2Q3X3Byb3ApIDwtIGMoIkQuNyIsICJHcm91cCIsICJDb3VudCIpDQojIGFkZCBhIGxhYmVsbGVkIGNvbHVtbg0Kc3VydmV5X2Q3X3Byb3AgPC0gc3VydmV5X2Q3X3Byb3AgJT4lDQogIG11dGF0ZShELjdfbGFiZWwgPSBjYXNlX3doZW4oDQogICAgRC43ID09ICIxIiB+ICIxLTQwJSIsDQogICAgRC43ID09ICIyIiB+ICIyLTUwJSIsDQogICAgRC43ID09ICIzIiB+ICIzLTYwJSIsDQogICAgRC43ID09ICI0IiB+ICI0LWRvIG5vdCB0aGluayBhYm91dCBwcm9iYWJpbGl0eSIsDQogICAgRC43ID09ICI1IiB+ICI1LWFsd2F5cyBjaG9vc2UgYSBub21pbmFsIGJvbmQiLA0KICAgIEQuNyA9PSAiNyIgfiAiNi03MCUiLA0KICAgIEQuNyA9PSAiOCIgfiAiNy04MCUiDQogICkpDQojIGNhbGN1bGF0ZSBwcm9wb3J0aW9ucyB3aXRoaW4gZWFjaCBncm91cA0Kc3VydmV5X2Q3X3Byb3AgPC0gc3VydmV5X2Q3X3Byb3AgJT4lDQogIGdyb3VwX2J5KEdyb3VwKSAlPiUNCiAgbXV0YXRlKFByb3BvcnRpb24gPSBDb3VudCAvIHN1bShDb3VudCkpDQpnZ3Bsb3Qoc3VydmV5X2Q3X3Byb3AsIGFlcyh4ID0gYXMuZmFjdG9yKGBELjdfbGFiZWxgKSwgeSA9IFByb3BvcnRpb24sIGZpbGwgPSBHcm91cCkpICsgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogICMgZmFjZXRfd3JhcCh+R3JvdXApKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkQuNyBBbnN3ZXIgUHJvcG90aW9uIFBsb3QgYWNyb3NzIEdyb3VwcyIsDQogICAgeCA9ICJSZXNwb25zZSIsDQogICAgeSA9ICJQcm9wb3J0aW9uIg0KICApICsNCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KUGxvdCB0aGUgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCiMgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpnZ3Bsb3Qoc3VydmV5X2Q3LCBhZXMoeCA9IGQ3X3ZhbHVlKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEsIGZpbGwgPSAic3RlZWxibHVlIiwgY29sb3IgPSAid2hpdGUiKSArDQogICMgZmFjZXRfd3JhcCh+IGdyb3VwKSArDQogIGxhYnModGl0bGUgPSAiRC43IEhpc3RvZ3JhbSIsDQogICAgICAgeCA9ICJELjciLA0KICAgICAgIHkgPSAiQ291bnQiKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgbWF4KHN1cnZleV9kNyRkN192YWx1ZSwgbmEucm0gPSBUUlVFKSwgYnkgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KIyMgRC44IEltcGFjdCBvbiBEZXNpY2lvbi1tYWtpbmcNCkNvbnNpZGVyaW5nIHRoZSBwYXlvZmYgZm9yIHRoZSBOb21pbmFsIEJvbmQsIHdoaWNoIG9mIHRoZSBmb2xsb3dpbmcgaGFzIGEgbGFyZ2VyIGltcGFjdCBvbiB5b3VyIGRlY2lzaW9uLW1ha2luZz9cDQpWYXJpYWJsZTogY2F0ZWdvcmljYWxcDQpNZXRob2Q6IGNvbnRpbmdlbmN5IHRhYmxlICYgY2hpLXNxdWFyZWQgdGVzdFwNCioqUmVzdWx0OiBGYWlsIHRvIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzLioqDQpgYGB7cn0NCiMgY29tYmluZSBkYXRhIGZyb20gZGlmZmVyZW50IGdyb3Vwcw0Kc3VydmV5X2Q4IDwtIGRhdGEuZnJhbWUoKQ0Kc3VydmV5X2Q4X2xpc3QgPC0gbGlzdCgiUTUuOCIsIlE3LjgiLCAiUTkuOCIsICJRMTEuOCIsICJRMTMuOCIpDQpmb3IgKGkgaW4gc2VxX2Fsb25nKGdyb3VwX2xpc3QpKSB7DQogIGRmIDwtIGdyb3VwX2xpc3RbW2ldXQ0KICBjb2wgPC0gc3VydmV5X2Q4X2xpc3RbW2ldXQ0KICB0ZW1wX3RhYmxlIDwtIGRmWywgYyhjb2wsICJncm91cCIpXQ0KICBuYW1lcyh0ZW1wX3RhYmxlKSA8LSBjKCJkOF92YWx1ZSIsICJncm91cCIpDQogIHN1cnZleV9kOCA8LSByYmluZChzdXJ2ZXlfZDgsIHRlbXBfdGFibGUpDQp9DQpzdXJ2ZXlfZDgkZDhfdmFsdWUgPC0gYXMubnVtZXJpYyhzdXJ2ZXlfZDgkZDhfdmFsdWUpDQpgYGANCkNvbnRpbmdlbmN5IHRhYmxlDQpgYGB7cn0NCnN1cnZleV9kOF9jb250aW5nZW5jeSA8LSB0YWJsZShzdXJ2ZXlfZDgkZDhfdmFsdWUsIHN1cnZleV9kOCRncm91cCkNCnByaW50KHN1cnZleV9kOF9jb250aW5nZW5jeSkNCiMgcnVuIGNoaS1zcXVhcmVkIHRlc3QNCmNoaXNxX3Jlc3VsdCA8LSBjaGlzcS50ZXN0KHN1cnZleV9kOF9jb250aW5nZW5jeSkNCnByaW50KGNoaXNxX3Jlc3VsdCkNCmBgYA0KUGxvdCBwcm9wb3J0aW9uIGJhciBwbG90IGFjcm9zcyBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCnN1cnZleV9kOF9wcm9wICA8LSBhcy5kYXRhLmZyYW1lKHN1cnZleV9kOF9jb250aW5nZW5jeSkNCiMgcmVuYW1lIGNvbHVtbnMNCm5hbWVzKHN1cnZleV9kOF9wcm9wKSA8LSBjKCJELjgiLCAiR3JvdXAiLCAiQ291bnQiKQ0KIyBhZGQgYSBsYWJlbGxlZCBjb2x1bW4NCnN1cnZleV9kOF9wcm9wIDwtIHN1cnZleV9kOF9wcm9wICU+JQ0KICBtdXRhdGUoRC44X2xhYmVsID0gY2FzZV93aGVuKA0KICAgIEQuOCA9PSAiMSIgfiAiMS1wb3RlbnRpYWwgbG9zcyIsDQogICAgRC44ID09ICIyIiB+ICIyLXBvdGVudGlhbCBnYWluIiwNCiAgICBELjggPT0gIjMiIH4gIjMtcG90ZW50aWFsIGxvc3MgYW5kIGdhaW4gaGF2ZSB0aGUgc2FtZSBpbXBhY3QiDQogICkpDQojIGNhbGN1bGF0ZSBwcm9wb3J0aW9ucyB3aXRoaW4gZWFjaCBncm91cA0Kc3VydmV5X2Q4X3Byb3AgPC0gc3VydmV5X2Q4X3Byb3AgJT4lDQogIGdyb3VwX2J5KEdyb3VwKSAlPiUNCiAgbXV0YXRlKFByb3BvcnRpb24gPSBDb3VudCAvIHN1bShDb3VudCkpDQpnZ3Bsb3Qoc3VydmV5X2Q4X3Byb3AsIGFlcyh4ID0gYXMuZmFjdG9yKGBELjhfbGFiZWxgKSwgeSA9IFByb3BvcnRpb24sIGZpbGwgPSBHcm91cCkpICsgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogICMgZmFjZXRfd3JhcCh+R3JvdXApKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkQuOCBBbnN3ZXIgUHJvcG90aW9uIFBsb3QgYWNyb3NzIEdyb3VwcyIsDQogICAgeCA9ICJSZXNwb25zZSIsDQogICAgeSA9ICJQcm9wb3J0aW9uIg0KICApICsNCiAgIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArDQogIHRoZW1lX21pbmltYWwoKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KUGxvdCB0aGUgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCiMgaGlzdG9ncmFtIGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpnZ3Bsb3Qoc3VydmV5X2Q4LCBhZXMoeCA9IGQ4X3ZhbHVlKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEsIGZpbGwgPSAic3RlZWxibHVlIiwgY29sb3IgPSAid2hpdGUiKSArDQogICMgZmFjZXRfd3JhcCh+IGdyb3VwKSArDQogIGxhYnModGl0bGUgPSAiRC44IEhpc3RvZ3JhbSIsDQogICAgICAgeCA9ICJELjgiLA0KICAgICAgIHkgPSAiQ291bnQiKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgbWF4KHN1cnZleV9kOCRkOF92YWx1ZSwgbmEucm0gPSBUUlVFKSwgYnkgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQojIyBELjkgRWZmZWN0aXZlbmVzcyBvZiB0aGUgZ3JhcGggZm9yIGRlY2lzaW9uLW1ha2luZw0KT24gYSBzY2FsZSBvZiAxIHRvIDEwLCB3aGVyZSAxIG1lYW5zIHRoZSBmb3JlY2FzdCB3YXMgbm90IGVmZmVjdGl2ZSBhdCBhbGwgYW5kIDEwIG1lYW5zIGl0IHdhcyB2ZXJ5IGVmZmVjdGl2ZSwgaG93IGVmZmVjdGl2ZSBkbyB5b3UgdGhpbmsgdGhlIGZvcmVjYXN0IHdhcyBpbiBhc3Npc3RpbmcgeW91ciBkZWNpc2lvbi1tYWtpbmc/XA0KKjEtTm90IGVmZmVjdGl2ZSBhdCBhbGw7IDEwLVZlcnkgZWZmZWN0aXZlKlwNClZhcmlhYmxlOiBjb250aW51b3VzXA0KTWV0aG9kOiBBTk5PVkEgdGVzdCBvciBLVyB0ZXN0IChkZXBlbmRzIG9uIHdoZXRoZXIgaXQncyBub3JtYWxseSBkaXN0cmlidXRlZClcDQoqKlJlc3VsdDogQXQgbGVhc3Qgb25lIGdyb3VwIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgdGhhbiBvdGhlcnMuICoqDQpgYGB7cn0NCiMgY29tYmluZSBkYXRhIGZyb20gZGlmZmVyZW50IGdyb3Vwcw0Kc3VydmV5X2Q5IDwtIGRhdGEuZnJhbWUoKQ0Kc3VydmV5X2Q5X2xpc3QgPC0gbGlzdCgiUTUuOV8xIiwiUTcuOV8xIiwgIlE5LjlfMSIsICJRMTEuOV8xIiwgIlExMy45XzEiKQ0KZm9yIChpIGluIHNlcV9hbG9uZyhncm91cF9saXN0KSkgew0KICBkZiA8LSBncm91cF9saXN0W1tpXV0NCiAgY29sIDwtIHN1cnZleV9kOV9saXN0W1tpXV0NCiAgdGVtcF90YWJsZSA8LSBkZlssIGMoY29sLCAiZ3JvdXAiKV0NCiAgbmFtZXModGVtcF90YWJsZSkgPC0gYygiZDlfdmFsdWUiLCAiZ3JvdXAiKQ0KICBzdXJ2ZXlfZDkgPC0gcmJpbmQoc3VydmV5X2Q5LCB0ZW1wX3RhYmxlKQ0KfQ0Kc3VydmV5X2Q5JGQ5X3ZhbHVlIDwtIGFzLm51bWVyaWMoc3VydmV5X2Q5JGQ5X3ZhbHVlKQ0KYGBgDQpTdGF0aXN0aWNhbCB0ZXN0DQpgYGB7cn0NCiMgSW5pdGlhbCBDaGVjaw0KIyBzdW1tYXJ5KHN1cnZleV9kOSRkOV92YWx1ZSkNCiMgY2hlY2sgbm9ybWFsaXR5IC0tPiB0aGUgZGF0YSBpcyBub3Qgbm9ybWFsbHkgZGlzdHJpYnV0ZWQNCiMgc2hhcGlyby50ZXN0KHN1cnZleV9kOSRkOV92YWx1ZSkNCg0KIyBydW4gS3J1c2thbC1XYWxsaXMgdGVzdA0Ka3J1c2thbF90ZXN0IDwtIGtydXNrYWwudGVzdChkOV92YWx1ZSB+IGdyb3VwLCBkYXRhID0gc3VydmV5X2Q5KQ0KcHJpbnQoa3J1c2thbF90ZXN0KQ0KIyBQb3N0LWhvYyB0ZXN0DQpkdW5uVGVzdChkOV92YWx1ZSB+IGdyb3VwLCBkYXRhID0gc3VydmV5X2Q5LCBtZXRob2QgPSAiYm9uZmVycm9uaSIpDQpgYGANClN1bW1hcnkgc3RhdGlzdGljcw0KYGBge3J9DQojIFN1bW1hcnkgc3RhdGlzdGljcw0Kc3VydmV5X2Q5X3N1bW1hcnkgPC0gc3VydmV5X2Q5ICU+JQ0KICBncm91cF9ieShncm91cCkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBtZWFuID0gbWVhbihkOV92YWx1ZSwgbmEucm0gPSBUUlVFKSwNCiAgICBtZWRpYW4gPSBtZWRpYW4oZDlfdmFsdWUsIG5hLnJtID0gVFJVRSksDQogICAgc2QgPSBzZChkOV92YWx1ZSwgbmEucm0gPSBUUlVFKQ0KICApDQpgYGANCg0KUGxvdCB0aGUgZGlzdHJpYnV0aW9uIG9mIGRpZmZlcmVudCBncm91cHMNCmBgYHtyfQ0KIyBHcm91cGVkIGJhci1zdHlsZSBoaXN0b2dyYW0NCmdncGxvdChzdXJ2ZXlfZDksIGFlcyh4ID0gZmFjdG9yKGQ5X3ZhbHVlKSwgZmlsbCA9IGZhY3Rvcihncm91cCkpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikgKw0KICAjIGZhY2V0X3dyYXAofiBncm91cCkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkQuOSBUaGUgZGlzdHJpYnV0aW9uIG9mIGVmZmVjdGl2ZW5lc3Mgb2YgdGhlIGdyYXBoIGZvciBkZWNpc2lvbi1tYWtpbmcgYnkgZ3JvdXAiLA0KICAgIHggPSAiRC45IFJlc3BvbnNlIiwNCiAgICB5ID0gIkNvdW50IiwNCiAgICBmaWxsID0gIkdyb3VwIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KDQojIyA/IEQuMTIgU2tld2VkIEludmVzdG1lbnQgRGVjaXNpb24NCldoaWNoIGJvbmQgd291bGQgeW91IGNob29zZSB0byBpbnZlc3QgaW4/XA0KVmFyaWFibGU6IGNhdGVnb3JpY2FsXA0KTWV0aG9kOiBjb250aW5nZW5jeSB0YWJsZSAmIGNoaS1zcXVhcmVkIHRlc3RcDQoqKlJlc3VsdDogVGhlcmUgaXMgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiBhdCBsZWFzdCBvbmUgZ3JvdXAuKioNCmBgYHtyfQ0KIyBjb21iaW5lIGRhdGEgZnJvbSBkaWZmZXJlbnQgZ3JvdXBzDQpzdXJ2ZXlfZDEyIDwtIGRhdGEuZnJhbWUoKQ0Kc3VydmV5X2QxMl9saXN0IDwtIGxpc3QoIlE3LjEyIiwgIlE5LjEyIiwgIlExMS4xMiIsICJRMTMuMTIiKQ0KZm9yIChpIGluIHNlcV9hbG9uZyhza2V3ZWRfZ3JvdXBfbGlzdCkpIHsNCiAgZGYgPC0gc2tld2VkX2dyb3VwX2xpc3RbW2ldXQ0KICBjb2wgPC0gc3VydmV5X2QxMl9saXN0W1tpXV0NCiAgdGVtcF90YWJsZSA8LSBkZlssIGMoY29sLCAiZ3JvdXAiKV0NCiAgbmFtZXModGVtcF90YWJsZSkgPC0gYygiZDEyX3ZhbHVlIiwgImdyb3VwIikNCiAgc3VydmV5X2QxMiA8LSByYmluZChzdXJ2ZXlfZDEyLCB0ZW1wX3RhYmxlKQ0KfQ0Kc3VydmV5X2QxMiRkMTJfdmFsdWUgPC0gYXMubnVtZXJpYyhzdXJ2ZXlfZDEyJGQxMl92YWx1ZSkNCmBgYA0KQ29udGluZ2VuY3kgdGFibGUNCmBgYHtyfQ0Kc3VydmV5X2QxMl9jb250aW5nZW5jeSA8LSB0YWJsZShzdXJ2ZXlfZDEyJGQxMl92YWx1ZSwgc3VydmV5X2QxMiRncm91cCkNCnByaW50KHN1cnZleV9kMTJfY29udGluZ2VuY3kpDQojIHJ1biBjaGktc3F1YXJlZCB0ZXN0DQpjaGlzcV9yZXN1bHQgPC0gY2hpc3EudGVzdChzdXJ2ZXlfZDEyX2NvbnRpbmdlbmN5KQ0KIyBwcmludChjaGlzcV9yZXN1bHQpDQpzdGRfcmVzaWQgPC0gY2hpc3FfcmVzdWx0JHN0ZHJlcw0KcHJpbnQoc3RkX3Jlc2lkKQ0KDQojIHBhaXJ3aXNlIHByb3BvcnRpb24gdGVzdA0KcGFpcndpc2UucHJvcC50ZXN0KA0KICB4ID0gc3VydmV5X2QxMl9jb250aW5nZW5jeVsyLF0sDQogIG4gPSBjb2xTdW1zKHN1cnZleV9kMTJfY29udGluZ2VuY3kpLA0KICBwLmFkanVzdC5tZXRob2QgPSAiYm9uZmVycm9uaSIgIyBvciAiaG9sbSIsICJCSCINCikNCmBgYA0KUGxvdCBwcm9wb3J0aW9uIGJhciBwbG90IGFjcm9zcyBkaWZmZXJlbnQgZ3JvdXBzDQpgYGB7cn0NCnN1cnZleV9kMTJfcHJvcCAgPC0gYXMuZGF0YS5mcmFtZShzdXJ2ZXlfZDEyX2NvbnRpbmdlbmN5KQ0KIyByZW5hbWUgY29sdW1ucw0KbmFtZXMoc3VydmV5X2QxMl9wcm9wKSA8LSBjKCJELjEyIiwgIkdyb3VwIiwgIkNvdW50IikNCiMgYWRkIGEgbGFiZWxsZWQgY29sdW1uDQpzdXJ2ZXlfZDEyX3Byb3AgPC0gc3VydmV5X2QxMl9wcm9wICU+JQ0KICBtdXRhdGUoRC4xMl9sYWJlbCA9IGNhc2Vfd2hlbigNCiAgICBELjEyID09ICIxIiB+ICJBLiBOb21pbmFsIEJvbmQiLA0KICAgIEQuMTIgPT0gIjIiIH4gIkIuIEluZmxhdGlvbi1Qcm90ZWN0ZWQgQm9uZCINCiAgKSkNCiMgY2FsY3VsYXRlIHByb3BvcnRpb25zIHdpdGhpbiBlYWNoIGdyb3VwDQpzdXJ2ZXlfZDEyX3Byb3AgPC0gc3VydmV5X2QxMl9wcm9wICU+JQ0KICBncm91cF9ieShHcm91cCkgJT4lDQogIG11dGF0ZShQcm9wb3J0aW9uID0gQ291bnQgLyBzdW0oQ291bnQpKQ0KZ2dwbG90KHN1cnZleV9kMTJfcHJvcCwgYWVzKHggPSBhcy5mYWN0b3IoYEQuMTJfbGFiZWxgKSwgeSA9IFByb3BvcnRpb24sIGZpbGwgPSBHcm91cCkpICsgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogICMgZmFjZXRfd3JhcCh+R3JvdXApKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkQuMTIgQW5zd2VyIFByb3BvdGlvbiBQbG90IGFjcm9zcyBHcm91cHMiLA0KICAgIHggPSAiUmVzcG9uc2UiLA0KICAgIHkgPSAiUHJvcG9ydGlvbiINCiAgKSArDQogICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKw0KICB0aGVtZV9taW5pbWFsKCkrDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANClBsb3QgcGllIGNoYXJ0IGluY2x1ZGluZyBhbGwgcGFydGljaXBhbnRzDQpgYGB7cn0NCnN1cnZleV9kMTJfc3VtbWFyeSA8LSBzdXJ2ZXlfZDEyX3Byb3AgJT4lDQogIGdyb3VwX2J5KGBELjEyX2xhYmVsYCkgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9jb3VudCA9IHN1bShDb3VudCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IHRvdGFsX2NvdW50IC8gc3VtKHRvdGFsX2NvdW50KSwNCiAgICAgICAgIGBELjEyX2dyYXBoX2xhYmVsYCA9IHBhc3RlMChgRC4xMl9sYWJlbGAsICIgKCIsIHJvdW5kKHByb3BvcnRpb24gKiAxMDAsIDIpLCAiICUpIikpDQpnZ3Bsb3Qoc3VydmV5X2QxMl9zdW1tYXJ5LCBhZXMoeCA9ICIiLHkgPSBwcm9wb3J0aW9uLCBmaWxsID0gYEQuMTJfZ3JhcGhfbGFiZWxgKSkgKw0KICBnZW9tX2NvbCh3aWR0aCA9IDEpICsNCiAgY29vcmRfcG9sYXIodGhldGEgPSAieSIpICsNCiAgbGFicyh0aXRsZSA9ICJELjEyIEludmVzdG1lbnQgRGVjaXNpb24gU3VtbWFyeSBQaWUgQ2hhcnQiLA0KICAgICAgIHggPSAiIiwNCiAgICAgICB5ID0gIiIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpDQpgYGANCiMjIEQuMTMgU2tld2VkIENvbmZpZGVudGNlIGluIGRlY2lzaW9uLW1ha2luZw0KT24gYSBzY2FsZSBvZiAxIHRvIDEwLCB3aGVyZSAxIG1lYW5zIG5vdCBjb25maWRlbnQgYXQgYWxsIGFuZCAxMCBtZWFucyB2ZXJ5IGNvbmZpZGVudCwgaG93IGNvbmZpZGVudCAgYXJlIHlvdSBpbiBtYWtpbmcgdGhlIGRlY2lzaW9uP1wNCioxLU5vdCBjb25maWRlbnQgYXQgYWxsOyAxMC1WZXJ5IGNvbmZpZGVudCpcDQpWYXJpYWJsZTogY29udGludW91c1wNCk1ldGhvZDogQU5OT1ZBIHRlc3Qgb3IgS1cgdGVzdCAoZGVwZW5kcyBvbiB3aGV0aGVyIGl0J3Mgbm9ybWFsbHkgZGlzdHJpYnV0ZWQpXA0KKipSZXN1bHQ6IEF0IGxlYXN0IG9uZSBncm91cCBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHRoYW4gb3RoZXJzLiAqKg0KYGBge3J9DQojIGNvbWJpbmUgZGF0YSBmcm9tIGRpZmZlcmVudCBncm91cHMNCnN1cnZleV9kMTMgPC0gZGF0YS5mcmFtZSgpDQpzdXJ2ZXlfZDEzX2xpc3QgPC0gbGlzdCgiUTcuMTNfMSIsICJROS4xM18xIiwgIlExMS4xM18xIiwgIlExMy4xM18xIikNCmZvciAoaSBpbiBzZXFfYWxvbmcoc2tld2VkX2dyb3VwX2xpc3QpKSB7DQogIGRmIDwtIHNrZXdlZF9ncm91cF9saXN0W1tpXV0NCiAgY29sIDwtIHN1cnZleV9kMTNfbGlzdFtbaV1dDQogIHRlbXBfdGFibGUgPC0gZGZbLCBjKGNvbCwgImdyb3VwIildDQogIG5hbWVzKHRlbXBfdGFibGUpIDwtIGMoImQxM192YWx1ZSIsICJncm91cCIpDQogIHN1cnZleV9kMTMgPC0gcmJpbmQoc3VydmV5X2QxMywgdGVtcF90YWJsZSkNCn0NCnN1cnZleV9kMTMkZDEzX3ZhbHVlIDwtIGFzLm51bWVyaWMoc3VydmV5X2QxMyRkMTNfdmFsdWUpDQpgYGANClN0YXRpc3RpY2FsIHRlc3QNCmBgYHtyfQ0KIyBJbml0aWFsIENoZWNrDQojIHN1bW1hcnkoc3VydmV5X2QxMyRkMTNfdmFsdWUpDQojIGNoZWNrIG5vcm1hbGl0eSAtLT4gdGhlIGRhdGEgaXMgbm90IG5vcm1hbGx5IGRpc3RyaWJ1dGVkDQojIHNoYXBpcm8udGVzdChzdXJ2ZXlfZDEzJGQxM192YWx1ZSkNCg0KIyBydW4gS3J1c2thbC1XYWxsaXMgdGVzdA0Ka3J1c2thbF90ZXN0IDwtIGtydXNrYWwudGVzdChkMTNfdmFsdWUgfiBncm91cCwgZGF0YSA9IHN1cnZleV9kMTMpDQpwcmludChrcnVza2FsX3Rlc3QpDQoNCmBgYA0KU3VtbWFyeSBzdGF0aXN0aWNzDQpgYGB7cn0NCiMgU3VtbWFyeSBzdGF0aXN0aWNzDQpzdXJ2ZXlfZDEzX3N1bW1hcnkgPC0gc3VydmV5X2QxMyAlPiUNCiAgZ3JvdXBfYnkoZ3JvdXApICU+JQ0KICBzdW1tYXJpc2UoDQogICAgbWVhbiA9IG1lYW4oZDEzX3ZhbHVlLCBuYS5ybSA9IFRSVUUpLA0KICAgIG1lZGlhbiA9IG1lZGlhbihkMTNfdmFsdWUsIG5hLnJtID0gVFJVRSksDQogICAgc2QgPSBzZChkMTNfdmFsdWUsIG5hLnJtID0gVFJVRSkNCiAgKQ0KYGBgDQpQbG90IHRoZSBkaXN0cmlidXRpb24gb2YgZGlmZmVyZW50IGdyb3Vwcw0KYGBge3J9DQojIEdyb3VwZWQgYmFyLXN0eWxlIGhpc3RvZ3JhbQ0KZ2dwbG90KHN1cnZleV9kMTMsIGFlcyh4ID0gZmFjdG9yKGQxM192YWx1ZSksIGZpbGwgPSBmYWN0b3IoZ3JvdXApKSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgIyBmYWNldF93cmFwKH4gZ3JvdXApICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJELjEzIFRoZSBkaXN0cmlidXRpb24gb2YgY29uZmlkZW5jZSBpbiBkZWNpc2lvbi1tYWtpbmcgYnkgZ3JvdXAiLA0KICAgIHggPSAiRC4xMyBSZXNwb25zZSIsDQogICAgeSA9ICJDb3VudCIsDQogICAgZmlsbCA9ICJHcm91cCINCiAgKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCg0KIyBDcm9zcy10YWJ1bGF0aW9uDQojIyBDdXJyZW50IEluZmxhdGlvbiBLbm93bGVkZ2UgdnMuIEluZmxhdGlvbiBGb3JlY2FzdCBLbm93bGVkZ2UNCiMjIFNrZXdlZCBEYXRhIHZzLiBVbnNrZXdlZCBEYXRhICggdW5kZXJzdGFuZGluZyBhbmQgZGVjaXNpb24gbWFraW5nKQ0KIyMgRm9yIHBlb3BsZSB3aG8gY2FuIGNvcnJlY3RseSB1bmRlcnN0YW5kIHRoZSBwcm9iYWJpbGl0eSAoPyB3aGljaCksIHdoYXQgZGVjaXNpb24gZG8gdGhleSBtYWtlPyAtLT4gSSBhbSB0aGlua2luZyBwcm9wb3Rpb24gdGVzdCBzZWUgcmVkdWNlZCBwcm9iYWJpbGl0eS4gDQojIyBEb2VzIGZhbWlsYXJpdHkgd2l0aCB0aGUgZ3JhcGggdHlwZSBhZmZlY3QgdW5kZXJzdGFuZGluZyBhbmQgdGhlIGRlY2lzaW9uPw0KDQoNCg0KIyBTdGF0aXN0aWNhbCBUZXN0aW5nIDxhIG5hbWU9InN0YXRpc3RpY2FsLXRlc3RpbmciPjwvYT4NCiMjIEJhc2ljcw0KVHlwZSBJIGVycm9yLSBmYWxzZSBwb3NpdGl2ZXMgKHNheWluZyB0aGVyZSdzIGEgZGlmZmVyZW5jZSB3aGVuIHRoZXJlIGlzbid0KQ0KIyMgQ2hpLXNxdWFyZWQgdGVzdA0KIyMjIFBvc3QtaG9jIHRlc3QNCjEuIFN0YW5kYXJkaXplZCByZXNpZHVhbHMNCmBgYHtyfQ0KY2hpc3FfcmVzdWx0IDwtIGNoaXNxLnRlc3QocTNfNF9jb250aW5nZW5jeSkNCnN0ZF9yZXNpZCA8LSBjaGlzcV9yZXN1bHQkc3RkcmVzDQpwcmludChzdGRfcmVzaWQpDQpgYGANCkNlbGxzIHdpdGggYWJzb2x1dGUgdmFsdWUgPiB+MiAob3IgPiAxLjk2IGZvciA5NSUgY29uZmlkZW5jZSlpbmRpY2F0ZSAgY29udHJpYnV0aW5nIG1vc3QgdG8gdGhlIG92ZXJhbGwgY2hpLXNxdWFyZWRcDQoNCjIuIFBhaXJ3aXNlIHByb3BvcnRpb24gdGVzdHM6IGNhbiBvbmx5IGNvbXBhcmUgb25lIHZhbHVlDQpgYGB7cn0NCnBhaXJ3aXNlLnByb3AudGVzdCgNCiAgeCA9IHEzXzRfY29udGluZ2VuY3lbLCAxOm5jb2wocTNfNF9jb250aW5nZW5jeSldLCAgIyBjb3VudHMgcGVyIGdyb3VwDQogIG4gPSBjb2xTdW1zKHEzXzRfY29udGluZ2VuY3kpLCAgICAgICAgICAgICAgICAgICAgICMgdG90YWwgcGVyIGdyb3VwDQogIHAuYWRqdXN0Lm1ldGhvZCA9ICJib25mZXJyb25pIiAgICAgICAgICAgICAgICAgICAgICMgb3IgImhvbG0iLCAiQkgiDQopDQpgYGANCg0KDQojIyBBTk9WQSB0ZXN0DQpBTk9WQSBvbmx5IGNvbXBhcmVzIHRoZSBtZWFucyBvZiB0aGUgZ3JvdXBzLlwNCiMjIyBBc3N1bXB0aW9ucyBvZiBBTk9WQQ0KMS4gTm9ybWFsaXR5IG9mIHJlc2lkdWFscyB3aXRoaW4gZWFjaCBncm91cDogSWYgcC12YWx1ZTwwLjA1LCB0aGUgZGF0YSBpcyBub3Qgbm9ybWFsbHkgZGlzdHJpYnV0ZWRcDQpgYGB7cn0NCnNoYXBpcm8udGVzdChkZiR2YWx1ZSkNCmBgYA0KDQoyLiBIb21vZ2VuZWl0eSBvZiB2YXJpYW5jZXMgYWNyb3NzIGdyb3Vwcw0KYGBge3J9DQojIENoZWNrIHRoZSBhc3N1bXB0aW9uIG9mIGVxdWFsIHZhcmlhbmNlcyAoaG9tb2dlbmVpdHkgb2YgdmFyaWFuY2UpIGFjcm9zcyBncm91cHMgDQojIElmIHA8IDAuMDUsIHdlIGNhbiByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBvZiBlcXVhbCB2YXJpYW5jZXMsIG1lYW5pbmcgdGhlIHZhcmlhbmNlcyBhcmUgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgYWNyb3NzIGdyb3Vwcw0KYmFydGxldHQudGVzdChgUTMuMmAgfiBncm91cCwgZGF0YSA9IGFnZV90YWJsZSkgIyBpZiBkYXRhIGlzIG5vcm1hbGx5IGRpc3RyaWJ1dGVkDQojIExldmVuZSdzIHRlc3QgZm9yIGhvbW9nZW5laXR5IG9mIHZhcmlhbmNlIGlmIGRhdGEgbWF5IG5vdCBiZSBub3JtYWxseSBkaXN0cmlidXRlZA0KbGlicmFyeShjYXIpDQpsZXZlbmVUZXN0KHZhbHVlIH4gZ3JvdXAsIGRhdGEgPSB0aW1lX2R1cmF0aW9uX3RhYmxlKQ0KYGBgDQojIyMgUG9zdC1ob2MgdGVzdA0KSWYgQU5PVkEgaXMgc2lnbmlmaWNhbnQsIHdlIGNhbiBwZXJmb3JtIHBvc3QtaG9jIHRlc3RzIHRvIGRldGVybWluZSB3aGljaCBncm91cHMgYXJlIHNpZ25pZmljYW50bHkgZGlmZmVyZW50IGZyb20gZWFjaCBvdGhlci5cDQpgYGB7cn0NCiMgcG9zdC1ob2MgdGVzdA0KdHVrZXlfdGVzdCA8LSBUdWtleUhTRChhbm92YV90ZXN0KQ0KcHJpbnQodHVrZXlfdGVzdCkNCg0KYGBgDQoNCj4gTnVsbCBoeXBvdGhlc2lzIChI4oKAKTogQWxsIGdyb3VwIG1lYW5zIGFyZSBlcXVhbFwNCj4gQWx0ZXJuYXRpdmUgaHlwb3RoZXNpcyAoSOKCgSk6IEF0IGxlYXN0IG9uZSBncm91cCBtZWFuIGlzIGRpZmZlcmVudA0KDQojIyBLcnVza2FsLVdhbGxpcyB0ZXN0DQoobm9uLXBhcmFtZXRyaWMgdGVzdClcDQp3aGVuIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUgaXMgY29udGludW91cyBvciBvcmRpbmFsXA0Kd2hlbiB0aGUgYXNzdW1wdGlvbnMgb2Ygb25lLXdheSBBTk9WQSBhcmUgbm90IG1ldDogbm9ybWFsaXR5IGFuZCBlcXVhbCB2YXJpYW5jZXMNCg0KZS5nLiwgTGlrZXJ0LXNjYWxlIHJlc3BvbnNlcyAob3JkaW5hbCkgDQojIyMgUG9zdC1ob2MgdGVzdA0KYGBge3J9DQpsaWJyYXJ5KEZTQSkNCg0KZHVublRlc3QodmFsdWUgfiBncm91cCwgZGF0YSA9IGRmLCBtZXRob2QgPSAiYm9uZmVycm9uaSIpDQojIA0KYGBgDQoNCiMjIFByb3BvdGlvbiB0ZXN0IC1wcm9wLnRlc3QoKQ0KLSBwcm9wLnRlc3QoKTogYXQgbGVhc3Qgb25lIGdyb3VwIGRpZmZlcnMNCjxmb250IGNvbG9yPSJyZWQiPmNvbnRpbnVpdHkgY29ycmVjdGlvbj8/PC9mb250Pg0KVGhlIHByb3AudGVzdCgpIGZ1bmN0aW9uIG9ubHkgc3VwcG9ydHMgYWx0ZXJuYXRpdmUgPSAibGVzcyIgb3IgImdyZWF0ZXIiIHdoZW4gY29tcGFyaW5nIGEgc2luZ2xlIHByb3BvcnRpb24gdG8gYSBoeXBvdGhlc2l6ZWQgdmFsdWUg4oCUIG5vdCB3aGVuIGNvbXBhcmluZyBtdWx0aXBsZSBncm91cHMuDQotIHBhaXJ3aXNlLnByb3AudGVzdCgpOiAgaWRlbnRpZnlpbmcgd2hpY2ggc3BlY2lmaWMgcGFpcnMgb2YgZ3JvdXBzIGRpZmZlciBzaWduaWZpY2FudGx5IGluIHRoZWlyIHByb3BvcnRpb25zLCBjaG9vc2UgdGhlIHAuYWRqdXN0Lm1ldGhvZCA9ICJob2xtIiBvciAiYm9uZmVycm9uaSIgb3IgIkJIIg0K